Compare commits

..

20 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
31 changed files with 854 additions and 575 deletions

11
NEWS
View File

@@ -1,6 +1,17 @@
This file lists notable changes in each release. For the full history of all
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
Highlights:

View File

@@ -146,6 +146,7 @@ usb:v04F3p0C58*
usb:v04F3p0C7D*
usb:v04F3p0C7E*
usb:v04F3p0C82*
usb:v04F3p0C88*
ID_AUTOSUSPEND=1
ID_PERSIST=0
@@ -190,6 +191,7 @@ usb:v06CBp0123*
usb:v06CBp0126*
usb:v06CBp0129*
usb:v06CBp0168*
usb:v06CBp015F*
ID_AUTOSUSPEND=1
ID_PERSIST=0
@@ -257,6 +259,7 @@ usb:v138Ap0091*
ID_PERSIST=0
# Known unsupported devices
usb:v04E8p730B*
usb:v04F3p036B*
usb:v04F3p0C00*
usb:v04F3p0C4C*
@@ -279,6 +282,7 @@ usb:v06CBp00C9*
usb:v06CBp00D8*
usb:v06CBp00DA*
usb:v06CBp00DC*
usb:v06CBp00E4*
usb:v06CBp00E7*
usb:v06CBp00E9*
usb:v06CBp00FD*
@@ -294,6 +298,7 @@ usb:v0A5Cp5845*
usb:v0BDAp5812*
usb:v10A5p0007*
usb:v10A5p9200*
usb:v10A5p9800*
usb:v1188p9545*
usb:v138Ap0007*
usb:v138Ap003A*
@@ -315,6 +320,7 @@ usb:v1C7Ap0576*
usb:v27C6p5042*
usb:v27C6p5110*
usb:v27C6p5117*
usb:v27C6p5125*
usb:v27C6p5201*
usb:v27C6p521D*
usb:v27C6p5301*
@@ -326,6 +332,7 @@ usb:v27C6p5385*
usb:v27C6p538C*
usb:v27C6p538D*
usb:v27C6p5395*
usb:v27C6p5503*
usb:v27C6p5584*
usb:v27C6p55A2*
usb:v27C6p55A4*

View File

@@ -40,6 +40,8 @@ fp_device_has_feature
fp_device_has_storage
fp_device_supports_identify
fp_device_supports_capture
fp_device_get_persistent_data
fp_device_set_persistent_data
fp_device_is_open
fp_device_open
fp_device_close

View File

@@ -28,6 +28,7 @@ static const FpIdEntry id_table[] = {
{ .vid = 0x04f3, .pid = 0x0c7d, },
{ .vid = 0x04f3, .pid = 0x0c7e, },
{ .vid = 0x04f3, .pid = 0x0c82, },
{ .vid = 0x04f3, .pid = 0x0c88, },
{ .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */
};
@@ -758,6 +759,7 @@ identify_status_report (FpiDeviceElanmoc *self, int verify_status_id,
}
enum identify_states {
IDENTIFY_SET_MODE,
IDENTIFY_WAIT_FINGER,
IDENTIFY_NUM_STATES,
};
@@ -793,6 +795,13 @@ elan_identify_run_state (FpiSsm *ssm, FpDevice *dev)
fp_info ("elanmoc %s ", __func__);
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:
fp_info ("elanmoc %s VERIFY_WAIT_FINGER", __func__);
cmd_buf = elanmoc_compose_cmd (&elanmoc_verify_cmd);

View File

@@ -63,7 +63,6 @@ struct _FpiDeviceElanSpi
guint16 gdac_step;
guint16 best_gdac;
guint16 best_meandiff;
guint16 target_mean;
} hv_data;
};
@@ -409,10 +408,6 @@ elanspi_determine_sensor (FpiDeviceElanSpi *self, GError **err)
self->frame_width = self->sensor_width;
self->frame_height = self->sensor_height > ELANSPI_MAX_FRAME_HEIGHT ? ELANSPI_MAX_FRAME_HEIGHT : self->sensor_height;
}
/* check x571 flag */
if (self->sensor_id == 0xe)
self->hv_data.target_mean = (fpi_device_get_driver_data (FP_DEVICE (self)) & ELANSPI_QUIRK_X571 ? ELANSPI_HV_X571_CALIBRATION_TARGET_MEAN : ELANSPI_HV_CALIBRATION_TARGET_MEAN);
}
static void
@@ -547,7 +542,7 @@ elanspi_write_regtable (FpiDeviceElanSpi *self, const struct elanspi_regtable *
for (int i = 0; table->entries[i].table; i += 1)
{
if (table->entries[i].sid == self->sensor_id && table->entries[i].quirk == (fpi_device_get_driver_data (FP_DEVICE (self)) & ELANSPI_QUIRK_MASK))
if (table->entries[i].sid == self->sensor_id)
{
starting_entry = table->entries[i].table;
break;
@@ -697,8 +692,6 @@ static void
elanspi_capture_hv_image_handler (FpiSpiTransfer *transfer, FpDevice *dev, gpointer unused_data, GError *error)
{
FpiDeviceElanSpi *self = FPI_DEVICE_ELANSPI (dev);
ptrdiff_t outptr = 0, inptr = 0;
guint16 value = 0;
if (error)
{
@@ -706,39 +699,24 @@ elanspi_capture_hv_image_handler (FpiSpiTransfer *transfer, FpDevice *dev, gpoin
return;
}
if (fpi_device_get_driver_data (dev) & ELANSPI_QUIRK_X571)
int i, outptr;
guint16 value = 0;
for (i = 0, outptr = 0; i < transfer->length_rd && outptr < (self->sensor_height * self->sensor_width * 2); i += 1)
{
/* decode image in x571 mode (just copy and fix endian) */
for (int y = 0; y < self->sensor_height; y += 1)
if (transfer->buffer_rd[i] != 0xff)
{
inptr += 2; /* 2 dummy bytes per line at start */
for (int x = 0; x < self->sensor_width; x += 1)
if (outptr % 2)
{
self->last_image[outptr / 2] = transfer->buffer_rd[inptr] + transfer->buffer_rd[inptr + 1] * 0x100;
inptr += 2;
outptr += 2;
value <<= 8;
value |= transfer->buffer_rd[i];
self->last_image[outptr / 2] = value;
}
}
}
else
{
/* decode image (normal case; with weird 0xff checks) */
for (inptr = 0, outptr = 0; inptr < transfer->length_rd && outptr < (self->sensor_height * self->sensor_width * 2); inptr += 1)
{
if (transfer->buffer_rd[inptr] != 0xff)
else
{
if (outptr % 2)
{
value <<= 8;
value |= transfer->buffer_rd[inptr];
self->last_image[outptr / 2] = value;
}
else
{
value = transfer->buffer_rd[inptr];
}
outptr += 1;
value = transfer->buffer_rd[i];
}
outptr += 1;
}
}
@@ -796,17 +774,12 @@ elanspi_capture_hv_handler (FpiSsm *ssm, FpDevice *dev)
return;
}
/* otherwise, read the image
* the hv sensors seem to use variable-length padding(?) this is only tested on the 0xe sensors
*
* in the x571 mode, the padding appears to be disabled and it just has 2 bytes of junk */
* the hv sensors seem to use 128 bytes of padding(?) this is only tested on the 0xe sensors */
xfer = fpi_spi_transfer_new (dev, self->spi_fd);
xfer->ssm = ssm;
fpi_spi_transfer_write (xfer, 2);
xfer->buffer_wr[0] = 0x10; /* receieve line/image */
if (fpi_device_get_driver_data (dev) & ELANSPI_QUIRK_X571)
fpi_spi_transfer_read (xfer, self->sensor_height * (self->sensor_width * 2 + 2) - 2);
else
fpi_spi_transfer_read (xfer, self->sensor_height * (self->sensor_width * 2 + 48));
xfer->buffer_wr[0] = 0x10; /* receieve line */
fpi_spi_transfer_read (xfer, self->sensor_height * (self->sensor_width * 2 + 48));
fpi_spi_transfer_submit (xfer, fpi_device_get_cancellable (dev), elanspi_capture_hv_image_handler, NULL);
return;
}
@@ -900,7 +873,7 @@ elanspi_calibrate_hv_handler (FpiSsm *ssm, FpDevice *dev)
case ELANSPI_CALIBHV_PROCESS:
/* compute mean */
mean_diff = abs (elanspi_mean_image (self, self->last_image) - self->hv_data.target_mean);
mean_diff = abs (elanspi_mean_image (self, self->last_image) - ELANSPI_HV_CALIBRATION_TARGET_MEAN);
if (mean_diff < 100)
{
fp_dbg ("<calibhv> calibration ok (mdiff < 100 w/ gdac=%04x)", self->hv_data.gdac_value);
@@ -923,7 +896,7 @@ elanspi_calibrate_hv_handler (FpiSsm *ssm, FpDevice *dev)
return;
}
/* update gdac */
if (elanspi_mean_image (self, self->last_image) < self->hv_data.target_mean)
if (elanspi_mean_image (self, self->last_image) < ELANSPI_HV_CALIBRATION_TARGET_MEAN)
self->hv_data.gdac_value -= self->hv_data.gdac_step;
else
self->hv_data.gdac_value += self->hv_data.gdac_step;

View File

@@ -71,7 +71,6 @@ struct elanspi_regtable
struct
{
unsigned char sid;
unsigned quirk;
const struct elanspi_reg_entry *table;
} entries[];
};
@@ -173,11 +172,11 @@ static const struct elanspi_reg_entry elanspi_calibration_table_id0[] = {
static const struct elanspi_regtable elanspi_calibration_table_old = {
.other = elanspi_calibration_table_default,
.entries = {
{ .sid = 0x0, .quirk = 0, .table = elanspi_calibration_table_id0 },
{ .sid = 0x5, .quirk = 0, .table = elanspi_calibration_table_id57 },
{ .sid = 0x6, .quirk = 0, .table = elanspi_calibration_table_id6 },
{ .sid = 0x7, .quirk = 0, .table = elanspi_calibration_table_id57 },
{ .sid = 0x0, .quirk = 0, .table = NULL }
{ .sid = 0x0, .table = elanspi_calibration_table_id0 },
{ .sid = 0x5, .table = elanspi_calibration_table_id57 },
{ .sid = 0x6, .table = elanspi_calibration_table_id6 },
{ .sid = 0x7, .table = elanspi_calibration_table_id57 },
{ .sid = 0x0, .table = NULL }
}
};
@@ -313,133 +312,20 @@ static const struct elanspi_reg_entry elanspi_calibration_table_page1_id14[] = {
{0xff, 0xff}
};
static const struct elanspi_reg_entry elanspi_calibration_table_page0_id14_x571[] = {
{0x00, 0x5a},
{0x01, 0x00},
{0x02, 0x4f},
{0x03, 0x00},
{0x09, 0x04},
{0x04, 0x4f},
{0x05, 0xa0},
{0x06, 0x57},
{0x07, 0x02},
{0x08, 0x00},
{0x0a, 0x63},
{0x0b, 0x01},
{0x0c, 0x08},
{0x0d, 0x00},
{0x0e, 0x00},
{0x0f, 0x13},
{0x10, 0x38},
{0x11, 0x01},
{0x12, 0x04},
{0x13, 0x00},
{0x14, 0x00},
{0x15, 0x04},
{0x16, 0x02},
{0x17, 0x00},
{0x18, 0x01},
{0x19, 0xf4},
{0x1a, 0x00},
{0x1b, 0x00},
{0x1c, 0x00},
{0x1d, 0x00},
{0x1e, 0x00},
{0x1f, 0x00},
{0x20, 0x00},
{0x21, 0x00},
{0x22, 0x06},
{0x23, 0x00},
{0x24, 0x00},
{0x25, 0x00},
{0x26, 0x00},
{0x27, 0xff},
{0x28, 0x00},
{0x29, 0x04},
{0x2b, 0xe2},
{0x2e, 0xd0},
{0x2f, 0x40},
{0x30, 0x01},
{0x31, 0x38},
{0x32, 0x00},
{0x33, 0x00},
{0x34, 0x00},
{0x35, 0x1f},
{0x36, 0xff},
{0x37, 0x00},
{0x38, 0x00},
{0x39, 0x00},
{0x3a, 0x00},
{0x2a, 0x5f},
{0x2c, 0x10},
{0xff, 0xff}
static const struct elanspi_regtable elanspi_calibration_table_new_page0 = {
.other = NULL,
.entries = {
{ .sid = 0xe, .table = elanspi_calibration_table_page0_id14 },
{ .sid = 0x0, .table = NULL }
}
};
static const struct elanspi_reg_entry elanspi_calibration_table_page1_id14_x571[] = {
{0x00, 0xfb},
{0x01, 0xff},
{0x02, 0x7f},
{0x03, 0xd4},
{0x04, 0x7d},
{0x05, 0x19},
{0x06, 0x80},
{0x07, 0x40},
{0x08, 0x11},
{0x09, 0x00},
{0x0a, 0x00},
{0x0b, 0x00},
{0x0c, 0x00},
{0x0d, 0x00},
{0x0e, 0x32},
{0x0f, 0x00},
{0x10, 0x00},
{0x11, 0x32},
{0x12, 0x02},
{0x13, 0x08},
{0x14, 0x5c},
{0x15, 0x01},
{0x16, 0x15},
{0x17, 0x01},
{0x18, 0x14},
{0x19, 0x01},
{0x1a, 0x14},
{0x1b, 0x01},
{0x1c, 0x16},
{0x1d, 0x01},
{0x1e, 0x0b},
{0x1f, 0x01},
{0x20, 0x0b},
{0x21, 0x02},
{0x22, 0x08},
{0x23, 0x29},
{0x24, 0x00},
{0x25, 0x0c},
{0x26, 0x1b},
{0x27, 0x15},
{0x28, 0x1b},
{0x29, 0x15},
{0x2a, 0x00},
{0x2b, 0x00},
{0x2c, 0x01},
{0x2d, 0x16},
{0x2e, 0x01},
{0x2f, 0x16},
{0x30, 0x04},
{0x31, 0x44},
{0x32, 0x04},
{0x33, 0x44},
{0x34, 0x14},
{0x35, 0x00},
{0x36, 0x00},
{0x37, 0x00},
{0x38, 0x00},
{0x39, 0x03},
{0x3a, 0xfe},
{0x3b, 0x00},
{0x3c, 0x00},
{0x3d, 0x02},
{0x3e, 0x00},
{0x3f, 0x00}
static const struct elanspi_regtable elanspi_calibration_table_new_page1 = {
.other = NULL,
.entries = {
{ .sid = 0xe, .table = elanspi_calibration_table_page1_id14 },
{ .sid = 0x0, .table = NULL }
}
};
#define ELANSPI_NO_ROTATE 0
@@ -449,33 +335,10 @@ static const struct elanspi_reg_entry elanspi_calibration_table_page1_id14_x571[
#define ELANSPI_HV_FLIPPED 1
#define ELANSPI_ROTATE_MASK 3
#define ELANSPI_QUIRK_X571 (1 << 2)
#define ELANSPI_QUIRK_MASK (ELANSPI_QUIRK_X571)
#define ELANSPI_UDEV_TYPES FPI_DEVICE_UDEV_SUBTYPE_SPIDEV | FPI_DEVICE_UDEV_SUBTYPE_HIDRAW
#define ELANSPI_TP_VID 0x04f3
static const struct elanspi_regtable elanspi_calibration_table_new_page0 = {
.other = NULL,
.entries = {
{ .sid = 0xe, .quirk = 0, .table = elanspi_calibration_table_page0_id14 },
{ .sid = 0xe, .quirk = ELANSPI_QUIRK_X571, .table = elanspi_calibration_table_page0_id14_x571 },
{ .sid = 0x0, .table = NULL }
}
};
static const struct elanspi_regtable elanspi_calibration_table_new_page1 = {
.other = NULL,
.entries = {
{ .sid = 0xe, .quirk = 0, .table = elanspi_calibration_table_page1_id14 },
{ .sid = 0xe, .quirk = ELANSPI_QUIRK_X571, .table = elanspi_calibration_table_page1_id14_x571 },
{ .sid = 0x0, .table = NULL }
}
};
// using checkargs ACPI:HIDPID
static const FpIdEntry elanspi_id_table[] = {
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3057}, .driver_data = ELANSPI_180_ROTATE},
{.udev_types = ELANSPI_UDEV_TYPES, .spi_acpi_id = "ELAN7001", .hid_id = {.vid = ELANSPI_TP_VID, .pid = 0x3087}, .driver_data = ELANSPI_180_ROTATE},
@@ -485,7 +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 = "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 = 0x3104}, .driver_data = ELANSPI_QUIRK_X571 | ELANSPI_90RIGHT_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}
};
@@ -495,7 +358,6 @@ static const FpIdEntry elanspi_id_table[] = {
#define ELANSPI_MAX_OLD_STAGE2_CALBIRATION_MEAN 8000
#define ELANSPI_HV_CALIBRATION_TARGET_MEAN 3000
#define ELANSPI_HV_X571_CALIBRATION_TARGET_MEAN 7000
#define ELANSPI_MIN_EMPTY_INVALID_PERCENT 6
#define ELANSPI_MAX_REAL_INVALID_PERCENT 3

View File

@@ -661,7 +661,7 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
/* */
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),
self->enroll_stage,
NULL,
@@ -675,7 +675,7 @@ fp_enroll_capture_cb (FpiDeviceGoodixMoc *self,
if ((resp->capture_data_resp.img_quality < self->sensorcfg->config[4]) ||
(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],
resp->capture_data_resp.img_quality,
self->sensorcfg->config[5],
@@ -1041,6 +1041,47 @@ fp_init_config_cb (FpiDeviceGoodixMoc *self,
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
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),
fp_init_config_cb);
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 {
FP_INIT_VERSION = 0,
FP_INIT_CONFIG,
FP_INIT_TEMPLATE_LIST,
FP_INIT_RESET_DEVICE,
FP_INIT_NUM_STATES,
} 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,
&presp->finger_list_resp.finger_list[num]) != 0)
{
g_error ("parse fingerlist error");
presp->finger_list_resp.finger_num = 0;
presp->result = GX_FAILED;
break;
g_warning ("Failed to parse finger list");
return -1;
}
offset += fingerid_length;
}

View File

@@ -43,6 +43,7 @@ static const FpIdEntry id_table[] = {
{ .vid = SYNAPTICS_VENDOR_ID, .pid = 0x0126, },
{ .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 */
};
@@ -225,6 +226,7 @@ cmd_interrupt_cb (FpiUsbTransfer *transfer,
}
else
{
fpi_device_critical_leave (device);
fpi_usb_transfer_submit (fpi_usb_transfer_ref (transfer),
0,
NULL,

View File

@@ -61,6 +61,7 @@ typedef struct
FpDeviceFeature features;
guint64 driver_data;
GVariant *persistent_data;
gint nr_enroll_stages;
GSList *sources;
@@ -130,6 +131,9 @@ typedef struct
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,
gboolean enabled);
void fpi_device_update_temp (FpDevice *device,

View File

@@ -54,6 +54,7 @@ enum {
PROP_FPI_UDEV_DATA_SPIDEV,
PROP_FPI_UDEV_DATA_HIDRAW,
PROP_FPI_DRIVER_DATA,
PROP_FPI_PERSISTENT_DATA,
N_PROPS
};
@@ -235,6 +236,8 @@ fp_device_finalize (GObject *object)
g_clear_pointer (&priv->udev_data.spidev_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);
}
@@ -304,6 +307,10 @@ fp_device_get_property (GObject *object,
g_value_set_string (value, NULL);
break;
case PROP_FPI_PERSISTENT_DATA:
g_value_set_variant (value, priv->persistent_data);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -354,6 +361,11 @@ fp_device_set_property (GObject *object,
priv->driver_data = g_value_get_uint64 (value);
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:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -594,6 +606,21 @@ fp_device_class_init (FpDeviceClass *klass)
0,
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);
}
@@ -739,6 +766,139 @@ fp_device_get_temperature (FpDevice *device)
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:
* @device: A #FpDevice
@@ -949,16 +1109,6 @@ fp_device_close_finish (FpDevice *device,
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:
* @device: a #FpDevice
@@ -1009,48 +1159,7 @@ fp_device_suspend (FpDevice *device,
priv->suspend_resume_task = g_steal_pointer (&task);
/* 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;
}
fpi_device_suspend (device);
}
/**
@@ -1115,41 +1224,7 @@ fp_device_resume (FpDevice *device,
priv->suspend_resume_task = g_steal_pointer (&task);
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;
}
fpi_device_resume (device);
}
/**

View File

@@ -230,6 +230,15 @@ FpDeviceFeature fp_device_get_features (FpDevice *device);
gboolean fp_device_has_feature (FpDevice *device,
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 */
void fp_device_open (FpDevice *device,
GCancellable *cancellable,

View File

@@ -21,6 +21,7 @@
#define FP_COMPONENT "device"
#include <math.h>
#include <fcntl.h>
#include <errno.h>
#include "fpi-log.h"
@@ -866,16 +867,16 @@ fpi_device_critical_section_flush_idle_cb (FpDevice *device)
if (priv->suspend_queued)
{
cls->suspend (device);
priv->suspend_queued = FALSE;
fpi_device_suspend (device);
return G_SOURCE_CONTINUE;
}
if (priv->resume_queued)
{
cls->resume (device);
priv->resume_queued = FALSE;
fpi_device_resume (device);
return G_SOURCE_CONTINUE;
}
@@ -912,6 +913,7 @@ fpi_device_critical_leave (FpDevice *device)
return;
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,
(GSourceFunc) fpi_device_critical_section_flush_idle_cb,
device,
@@ -1550,6 +1552,148 @@ fpi_device_list_complete (FpDevice *device,
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
fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
{
@@ -1565,8 +1709,7 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
guint8 bus, port;
g_autofree gchar *sysfs_wakeup = NULL;
g_autofree gchar *sysfs_persist = NULL;
gssize r;
int fd;
int res;
ports = g_string_new (NULL);
bus = g_usb_device_get_bus (priv->usb_device);
@@ -1582,20 +1725,9 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
g_string_set_size (ports, ports->len - 1);
sysfs_wakeup = g_strdup_printf ("/sys/bus/usb/devices/%d-%s/power/wakeup", bus, ports->str);
fd = open (sysfs_wakeup, O_WRONLY);
if (fd < 0)
{
/* 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);
}
res = update_attr (sysfs_wakeup, wakeup_command);
if (res < 0)
g_debug ("Failed to set %s to %s", sysfs_wakeup, wakeup_command);
/* Persist means that the kernel tries to keep the USB device open
* in case it is "replugged" due to suspend.
@@ -1603,20 +1735,9 @@ fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
* 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);
fd = open (sysfs_persist, O_WRONLY);
if (fd < 0)
{
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);
}
res = update_attr (sysfs_persist, "0");
if (res < 0)
g_warning ("Failed to disable USB persist by writing to %s", sysfs_persist);
break;
}

View File

@@ -42,9 +42,9 @@ gboolean fpi_print_add_from_image (FpPrint *print,
FpImage *image,
GError **error);
FpiMatchResult fpi_print_bz3_match (FpPrint * template,
FpPrint * print,
gint bz3_threshold,
FpiMatchResult fpi_print_bz3_match (FpPrint *temp,
FpPrint *print,
gint bz3_threshold,
GError **error);
/* Helpers to encode metadata into user ID strings. */

View File

@@ -29,6 +29,7 @@ static const FpIdEntry whitelist_id_table[] = {
* 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'
*/
{ .vid = 0x04e8, .pid = 0x730b },
{ .vid = 0x04f3, .pid = 0x036b },
{ .vid = 0x04f3, .pid = 0x0c00 },
{ .vid = 0x04f3, .pid = 0x0c4c },
@@ -51,6 +52,7 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x06cb, .pid = 0x00d8 },
{ .vid = 0x06cb, .pid = 0x00da },
{ .vid = 0x06cb, .pid = 0x00dc },
{ .vid = 0x06cb, .pid = 0x00e4 },
{ .vid = 0x06cb, .pid = 0x00e7 },
{ .vid = 0x06cb, .pid = 0x00e9 },
{ .vid = 0x06cb, .pid = 0x00fd },
@@ -66,6 +68,7 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x0bda, .pid = 0x5812 },
{ .vid = 0x10a5, .pid = 0x0007 },
{ .vid = 0x10a5, .pid = 0x9200 },
{ .vid = 0x10a5, .pid = 0x9800 },
{ .vid = 0x1188, .pid = 0x9545 },
{ .vid = 0x138a, .pid = 0x0007 },
{ .vid = 0x138a, .pid = 0x003a },
@@ -87,6 +90,7 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x27c6, .pid = 0x5042 },
{ .vid = 0x27c6, .pid = 0x5110 },
{ .vid = 0x27c6, .pid = 0x5117 },
{ .vid = 0x27c6, .pid = 0x5125 },
{ .vid = 0x27c6, .pid = 0x5201 },
{ .vid = 0x27c6, .pid = 0x521d },
{ .vid = 0x27c6, .pid = 0x5301 },
@@ -98,6 +102,7 @@ static const FpIdEntry whitelist_id_table[] = {
{ .vid = 0x27c6, .pid = 0x538c },
{ .vid = 0x27c6, .pid = 0x538d },
{ .vid = 0x27c6, .pid = 0x5395 },
{ .vid = 0x27c6, .pid = 0x5503 },
{ .vid = 0x27c6, .pid = 0x5584 },
{ .vid = 0x27c6, .pid = 0x55a2 },
{ .vid = 0x27c6, .pid = 0x55a4 },

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 */
extern int verbose_threshold;
/* Global supporting error reporting */
extern FILE *stderr;
/**************************************************************************/
/* In: BZ_GBLS.C */

View File

@@ -198,3 +198,6 @@ patch -p0 < fix-scan-build-reports.patch
# Add pass to remove perimeter points
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' ],
version: '1.94.3',
version: '1.94.4',
license: 'LGPLv2.1+',
default_options: [
'buildtype=debugoptimized',

View File

@@ -120,7 +120,7 @@ nl_multi_line_cond true
# Not clear what to do about that...
mod_full_brace_for 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_do Remove
mod_full_brace_nl 3

View File

@@ -105,6 +105,11 @@ process.wait()
# Run capture
# 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}')
capture_pid = os.fork()
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
N: bus/usb/001/010=1201000200000040F3047E0C05030102000109025300010103A0320904000008FF0000000921100100012215000705810240000107050102400001070582024000010705020240000107058302400001070503024000010705840240000107050402400001
E: DEVNAME=/dev/bus/usb/001/010
P: /devices/pci0000:00/0000:00:14.0/usb1/1-9
N: bus/usb/001/003=1201000200000008F304880C04800102000109025300010100A0320904000008FF0000000921100100012215000705810240000107050102400001070582024000010705020240000107058302400001070503024000010705840240000107050402400001
E: DEVNAME=/dev/bus/usb/001/003
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=4f3/c7e/305
E: PRODUCT=4f3/c88/8004
E: TYPE=0/0/0
E: BUSNUM=001
E: DEVNUM=010
E: DEVNUM=003
E: MAJOR=189
E: MINOR=9
E: MINOR=2
E: SUBSYSTEM=usb
E: ID_VENDOR=ELAN
E: ID_VENDOR_ENC=ELAN
E: ID_VENDOR_ID=04f3
E: ID_MODEL=ELAN:ARM-M4
E: ID_MODEL_ENC=ELAN:ARM-M4
E: ID_MODEL_ID=0c7e
E: ID_REVISION=0305
E: ID_MODEL_ID=0c88
E: ID_REVISION=8004
E: ID_SERIAL=ELAN_ELAN:ARM-M4
E: ID_BUS=usb
E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp.
E: ID_PATH=pci-0000:00:14.0-usb-0:1
E: ID_PATH_TAG=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_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: avoid_reset_quirk=0\n
A: bConfigurationValue=1\n
A: bDeviceClass=00\n
A: bDeviceProtocol=00\n
A: bDeviceSubClass=00\n
A: bMaxPacketSize0=64\n
A: bMaxPacketSize0=8\n
A: bMaxPower=100mA\n
A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n
A: bcdDevice=0305\n
A: bcdDevice=8004\n
A: bmAttributes=a0\n
A: busnum=1\n
A: configuration=add909c9-e67e-4126-a6f7-1e31179e27d9\n
H: descriptors=1201000200000040F3047E0C05030102000109025300010103A0320904000008FF0000000921100100012215000705810240000107050102400001070582024000010705020240000107058302400001070503024000010705840240000107050402400001
A: dev=189:9\n
A: devnum=10\n
A: devpath=1\n
A: configuration=
H: descriptors=1201000200000008F304880C04800102000109025300010100A0320904000008FF0000000921100100012215000705810240000107050102400001070582024000010705020240000107058302400001070503024000010705840240000107050402400001
A: dev=189:2\n
A: devnum=3\n
A: devpath=9\n
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: ltm_capable=no\n
A: manufacturer=ELAN\n
A: maxchild=0\n
L: port=../1-0:1.0/usb1-port1
A: power/active_duration=94712\n
L: port=../1-0:1.0/usb1-port9
A: power/active_duration=35269124\n
A: power/async=enabled\n
A: power/autosuspend=2\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/level=on\n
A: power/persist=1\n
A: power/persist=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_status=active\n
A: power/runtime_suspended_time=0\n
@@ -77,38 +81,40 @@ A: removable=removable\n
A: rx_lanes=1\n
A: speed=12\n
A: tx_lanes=1\n
A: urbnum=12\n
A: urbnum=2773\n
A: version= 2.00\n
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: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=1d6b/2/504
E: PRODUCT=1d6b/2/515
E: TYPE=9/0/1
E: BUSNUM=001
E: DEVNUM=001
E: MAJOR=189
E: MINOR=0
E: SUBSYSTEM=usb
E: ID_VENDOR=Linux_5.4.0-42-generic_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.4.0-42-generic\x20xhci-hcd
E: ID_VENDOR=Linux_5.15.0-39-generic_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.15.0-39-generic\x20xhci-hcd
E: ID_VENDOR_ID=1d6b
E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_ID=0002
E: ID_REVISION=0504
E: ID_SERIAL=Linux_5.4.0-42-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_REVISION=0515
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_BUS=usb
E: ID_USB_INTERFACES=:090000:
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
E: ID_AUTOSUSPEND=1
E: ID_MODEL_FROM_DATABASE=2.0 root hub
E: ID_PATH=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: TAGS=:seat:
E: CURRENT_TAGS=:seat:
A: authorized=1\n
A: authorized_default=1\n
A: avoid_reset_quirk=0\n
@@ -120,30 +126,31 @@ A: bMaxPacketSize0=64\n
A: bMaxPower=0mA\n
A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n
A: bcdDevice=0504\n
A: bcdDevice=0515\n
A: bmAttributes=e0\n
A: busnum=1\n
A: configuration=\n
H: descriptors=12010002090001406B1D020004050302010109021900010100E0000904000001090000000705810304000C
A: configuration=
H: descriptors=12010002090001406B1D020015050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0\n
A: devnum=1\n
A: devpath=0\n
L: driver=../../../../bus/usb/drivers/usb
L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:3d/device:3e
A: idProduct=0002\n
A: idVendor=1d6b\n
A: interface_authorized_default=1\n
A: ltm_capable=no\n
A: manufacturer=Linux 5.4.0-42-generic xhci-hcd\n
A: maxchild=12\n
A: power/active_duration=74604360\n
A: manufacturer=Linux 5.15.0-39-generic xhci-hcd\n
A: maxchild=14\n
A: power/active_duration=35270364\n
A: power/async=enabled\n
A: power/autosuspend=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/level=auto\n
A: power/runtime_active_kids=4\n
A: power/runtime_active_time=74605838\n
A: power/runtime_active_kids=2\n
A: power/runtime_active_time=35277420\n
A: power/runtime_enabled=enabled\n
A: power/runtime_status=active\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: speed=480\n
A: tx_lanes=1\n
A: urbnum=490\n
A: urbnum=549\n
A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0
E: DRIVER=xhci_hcd
E: PCI_CLASS=C0330
E: PCI_ID=8086:9DED
E: PCI_SUBSYS_ID=103C:85EF
E: PCI_ID=8086:8C31
E: PCI_SUBSYS_ID=1043:201F
E: PCI_SLOT_NAME=0000:00:14.0
E: MODALIAS=pci:v00008086d00009DEDsv0000103Csd000085EFbc0Csc03i30
E: MODALIAS=pci:v00008086d00008C31sv00001043sd0000201Fbc0Csc03i30
E: SUBSYSTEM=pci
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
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: broken_parity_status=0\n
A: class=0x0c0330\n
H: config=8680ED9D060490023030030C00008000040030A10000000000000000000000000000000000000000000000003C10EF85000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F00000000181C030400000000316000000000000000000000000000000180C2C1080000000000000000000000059087007802E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000B50F300112000000
H: config=8680318C060490020530030C000000000400A0F700000000000000000000000000000000000000000000000043101F200000000070000000000000000B010000FD01368089C60F8000000000000000009F6E8807000000000000000000000000302000000000000000000000000000000180C2C1080000000000000000000000050087000410E0FE000000002F00000000000000000000000000000000000000400100000000000000000000000000000F000100000000000000000000000000030420C0030C3000030C300000000000FF1A0000FF1A00003F0000003F000000A00000000000000000000000D8D8D8080000000000000000B10F060800000000
A: consistent_dma_mask_bits=64\n
A: d3cold_allowed=1\n
A: dbc=disabled\n
A: device=0x9ded\n
A: device=0x8c31\n
A: dma_mask_bits=64\n
L: driver=../../../bus/pci/drivers/xhci_hcd
A: driver_override=(null)\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_cpus=f\n
A: modalias=pci:v00008086d00009DEDsv0000103Csd000085EFbc0Csc03i30\n
A: modalias=pci:v00008086d00008C31sv00001043sd0000201Fbc0Csc03i30\n
A: msi_bus=1\n
A: msi_irqs/124=msi\n
A: msi_irqs/31=msi\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/control=auto\n
A: power/control=on\n
A: power/runtime_active_kids=1\n
A: power/runtime_active_time=74606194\n
A: power/runtime_enabled=enabled\n
A: power/runtime_active_time=35278060\n
A: power/runtime_enabled=forbidden\n
A: power/runtime_status=active\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_abort_count=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_expire_count=0\n
A: power/wakeup_last_time_ms=0\n
A: power/wakeup_max_time_ms=0\n
A: power/wakeup_total_time_ms=0\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: revision=0x30\n
A: subsystem_device=0x85ef\n
A: subsystem_vendor=0x103c\n
A: power/wakeup_expire_count=5\n
A: power/wakeup_last_time_ms=12694896\n
A: power/wakeup_max_time_ms=103\n
A: power/wakeup_total_time_ms=518\n
A: power_state=D0\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: revision=0x05\n
A: subsystem_device=0x201f\n
A: subsystem_vendor=0x1043\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()
# 1. verify clear storage command, 2. make sure later asserts are good
d.clear_storage_sync()
template = FPrint.Print.new(d)
def enroll_progress(*args):

View File

@@ -1,14 +1,14 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-3
N: bus/usb/001/053=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000
E: DEVNAME=/dev/bus/usb/001/053
N: bus/usb/001/023=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000
E: DEVNAME=/dev/bus/usb/001/023
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=27c6/6496/100
E: TYPE=239/0/0
E: BUSNUM=001
E: DEVNUM=053
E: DEVNUM=023
E: MAJOR=189
E: MINOR=52
E: MINOR=22
E: SUBSYSTEM=usb
E: ID_VENDOR=Goodix_Technology_Co.__Ltd.
E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd.
@@ -23,6 +23,7 @@ E: ID_BUS=usb
E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd.
E: ID_AUTOSUSPEND=1
E: ID_PERSIST=0
E: ID_PATH=pci-0000:00:14.0-usb-0:3
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_3
A: authorized=1\n
@@ -40,8 +41,8 @@ A: bmAttributes=a0\n
A: busnum=1\n
A: configuration=XXXX_MOC_B0\n
H: descriptors=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000
A: dev=189:52\n
A: devnum=53\n
A: dev=189:22\n
A: devnum=23\n
A: devpath=3\n
L: driver=../../../../../bus/usb/drivers/usb
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: maxchild=0\n
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_delay_ms=2000\n
A: power/connected_duration=57399\n
A: power/connected_duration=917616\n
A: power/control=auto\n
A: power/level=auto\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_suspended_time=27850\n
A: power/runtime_suspended_time=894564\n
A: power/wakeup=disabled\n
A: power/wakeup_abort_count=\n
A: power/wakeup_active=\n
@@ -77,29 +78,29 @@ A: rx_lanes=1\n
A: serial=XXXX_MOC_B0\n
A: speed=12\n
A: tx_lanes=1\n
A: urbnum=394\n
A: urbnum=298\n
A: version= 2.00\n
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: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=1d6b/2/513
E: PRODUCT=1d6b/2/517
E: TYPE=9/0/1
E: BUSNUM=001
E: DEVNUM=001
E: MAJOR=189
E: MINOR=0
E: SUBSYSTEM=usb
E: ID_VENDOR=Linux_5.13.15-200.fc34.x86_64_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.13.15-200.fc34.x86_64\x20xhci-hcd
E: ID_VENDOR=Linux_5.17.12-300.fc36.x86_64_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.17.12-300.fc36.x86_64\x20xhci-hcd
E: ID_VENDOR_ID=1d6b
E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_ID=0002
E: ID_REVISION=0513
E: ID_SERIAL=Linux_5.13.15-200.fc34.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_REVISION=0517
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_BUS=usb
E: ID_USB_INTERFACES=:090000:
@@ -122,11 +123,11 @@ A: bMaxPacketSize0=64\n
A: bMaxPower=0mA\n
A: bNumConfigurations=1\n
A: bNumInterfaces= 1\n
A: bcdDevice=0513\n
A: bcdDevice=0517\n
A: bmAttributes=e0\n
A: busnum=1\n
A: configuration=\n
H: descriptors=12010002090001406B1D020013050302010109021900010100E0000904000001090000000705810304000C
H: descriptors=12010002090001406B1D020017050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0\n
A: devnum=1\n
A: devpath=0\n
@@ -136,15 +137,15 @@ A: idProduct=0002\n
A: idVendor=1d6b\n
A: interface_authorized_default=1\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: power/active_duration=219578717\n
A: power/active_duration=164289796\n
A: power/autosuspend=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/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_suspended_time=0\n
A: power/wakeup=disabled\n
@@ -163,14 +164,14 @@ A: rx_lanes=1\n
A: serial=0000:00:14.0\n
A: speed=480\n
A: tx_lanes=1\n
A: urbnum=4325\n
A: urbnum=2097\n
A: version= 2.00\n
P: /devices/pci0000:00/0000:00:14.0
E: DRIVER=xhci_hcd
E: PCI_CLASS=C0330
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: MODALIAS=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30
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: broken_parity_status=0\n
A: class=0x0c0330\n
H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F000000004C084B0100000000316000000000000000000000000000000180C2C1080000000000000000000000059087001803E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000
H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F00000000F507312600000000316000000000000000000000000000000180C2C1080000000000000000000000059087001803E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000
A: consistent_dma_mask_bits=64\n
A: d3cold_allowed=1\n
A: dbc=disabled\n
@@ -201,8 +202,8 @@ A: msi_bus=1\n
A: msi_irqs/128=msi\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: power/control=on\n
A: power/runtime_active_time=219589302\n
A: power/control=auto\n
A: power/runtime_active_time=164332777\n
A: power/runtime_status=active\n
A: power/runtime_suspended_time=0\n
A: power/wakeup=enabled\n

Binary file not shown.

View File

@@ -1,10 +1,14 @@
#!/usr/bin/python3
import os
import gi
gi.require_version('FPrint', '2.0')
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.enumerate()
@@ -13,6 +17,24 @@ devices = c.get_devices()
d = devices[0]
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 not d.has_feature(FPrint.DeviceFeature.CAPTURE)
assert d.has_feature(FPrint.DeviceFeature.IDENTIFY)
@@ -29,7 +51,7 @@ d.clear_storage_sync()
template = FPrint.Print.new(d)
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))
# List, enroll, list, verify, delete, list
@@ -41,6 +63,21 @@ print("enroll done")
print("verifying")
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)
assert d.get_finger_status() == FPrint.FingerStatusFlags.NONE
print("verify done")

View File

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

View File

@@ -232,6 +232,53 @@ test_device_has_storage (void)
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
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_capture", test_device_supports_capture);
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 ();
}