mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Compare commits
21 Commits
benzea/fix
...
V_1_0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
823f2c1067 | ||
|
|
19732341d6 | ||
|
|
0e44eb4c1c | ||
|
|
50461b4d7d | ||
|
|
c11126181e | ||
|
|
658c301e3c | ||
|
|
dce52ed081 | ||
|
|
f309f586c9 | ||
|
|
ae1b10dba8 | ||
|
|
860a256f4b | ||
|
|
cb2f46ed08 | ||
|
|
13deaa66fd | ||
|
|
3597a5b0ed | ||
|
|
0352995cb3 | ||
|
|
e9041da7f4 | ||
|
|
252180e088 | ||
|
|
6361c208bd | ||
|
|
2ef8ace543 | ||
|
|
0400bcc85e | ||
|
|
76db6a5a16 | ||
|
|
5b171f9577 |
113
.ci/check-abi
Executable file
113
.ci/check-abi
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def format_title(title):
|
||||
box = {
|
||||
'tl': '╔', 'tr': '╗', 'bl': '╚', 'br': '╝', 'h': '═', 'v': '║',
|
||||
}
|
||||
hline = box['h'] * (len(title) + 2)
|
||||
|
||||
return '\n'.join([
|
||||
f"{box['tl']}{hline}{box['tr']}",
|
||||
f"{box['v']} {title} {box['v']}",
|
||||
f"{box['bl']}{hline}{box['br']}",
|
||||
])
|
||||
|
||||
|
||||
def rm_rf(path):
|
||||
try:
|
||||
shutil.rmtree(path)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
def sanitize_path(name):
|
||||
return name.replace('/', '-')
|
||||
|
||||
|
||||
def get_current_revision():
|
||||
revision = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
|
||||
encoding='utf-8').strip()
|
||||
|
||||
if revision == 'HEAD':
|
||||
# This is a detached HEAD, get the commit hash
|
||||
revision = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode('utf-8')
|
||||
|
||||
return revision
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def checkout_git_revision(revision):
|
||||
current_revision = get_current_revision()
|
||||
subprocess.check_call(['git', 'checkout', '-q', revision])
|
||||
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
subprocess.check_call(['git', 'checkout', '-q', current_revision])
|
||||
|
||||
|
||||
def build_install(revision):
|
||||
build_dir = '_build'
|
||||
dest_dir = os.path.abspath(sanitize_path(revision))
|
||||
print(format_title(f'# Building and installing {revision} in {dest_dir}'),
|
||||
end='\n\n', flush=True)
|
||||
|
||||
with checkout_git_revision(revision):
|
||||
rm_rf(build_dir)
|
||||
rm_rf(revision)
|
||||
|
||||
subprocess.check_call(['meson', build_dir,
|
||||
'--prefix=/usr', '--libdir=lib',
|
||||
'-Dx11-examples=false', '-Ddoc=false', '-Dgtk-examples=false'])
|
||||
subprocess.check_call(['ninja', '-v', '-C', build_dir])
|
||||
subprocess.check_call(['ninja', '-v', '-C', build_dir, 'install'],
|
||||
env={'DESTDIR': dest_dir})
|
||||
|
||||
return dest_dir
|
||||
|
||||
|
||||
def compare(old_tree, new_tree):
|
||||
print(format_title(f'# Comparing the two ABIs'), end='\n\n', flush=True)
|
||||
|
||||
old_headers = os.path.join(old_tree, 'usr', 'include')
|
||||
old_lib = os.path.join(old_tree, 'usr', 'lib', 'libfprint.so')
|
||||
|
||||
new_headers = os.path.join(new_tree, 'usr', 'include')
|
||||
new_lib = os.path.join(new_tree, 'usr', 'lib', 'libfprint.so')
|
||||
|
||||
subprocess.check_call([
|
||||
'abidiff', '--headers-dir1', old_headers, '--headers-dir2', new_headers,
|
||||
'--drop-private-types', '--fail-no-debug-info', '--no-added-syms', old_lib, new_lib])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('old', help='the previous revision, considered the reference')
|
||||
parser.add_argument('new', help='the new revision, to compare to the reference')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.old == args.new:
|
||||
print("Let's not waste time comparing something to itself")
|
||||
sys.exit(0)
|
||||
|
||||
old_tree = build_install(args.old)
|
||||
new_tree = build_install(args.new)
|
||||
|
||||
try:
|
||||
compare(old_tree, new_tree)
|
||||
|
||||
except Exception:
|
||||
sys.exit(1)
|
||||
|
||||
print(f'Hurray! {args.old} and {args.new} are ABI-compatible!')
|
||||
@@ -7,6 +7,7 @@ variables:
|
||||
DEPENDENCIES: libusb1-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc
|
||||
gcc gcc-c++ glibc-devel libX11-devel libXv-devel gtk3-devel flatpak-builder
|
||||
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
|
||||
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
|
||||
|
||||
.build_one_driver_template: &build_one_driver
|
||||
script:
|
||||
@@ -24,10 +25,16 @@ variables:
|
||||
- ninja -C _build
|
||||
- ninja -C _build install
|
||||
|
||||
.build_template: &check_abi
|
||||
script:
|
||||
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES doxygen libabigail git
|
||||
- ./.ci/check-abi ${LAST_ABI_BREAK} $(git rev-parse HEAD)
|
||||
|
||||
build:
|
||||
stage: build
|
||||
<<: *build_one_driver
|
||||
<<: *build
|
||||
<<: *check_abi
|
||||
|
||||
.flatpak_script_template: &flatpak_script
|
||||
script:
|
||||
|
||||
25
HACKING.md
25
HACKING.md
@@ -3,8 +3,29 @@
|
||||
## GLib
|
||||
|
||||
Although the library uses GLib internally, libfprint is designed to provide
|
||||
a completely neutral interface to it's application users. So, the public
|
||||
APIs should never return GLib data types or anything like that.
|
||||
a completely neutral interface to its application users. So, the public
|
||||
APIs should never return GLib data types.
|
||||
|
||||
## License clarification
|
||||
|
||||
Although this library's license could allow for shims that hook up into
|
||||
proprietary blobs to add driver support for some unsupported devices, the
|
||||
intent of the original authors, and of current maintainers of the library,
|
||||
was for this license to allow _integration into_ proprietary stacks, not
|
||||
_integration of_ proprietary code in the library.
|
||||
|
||||
As such, no code to integrate proprietary drivers will be accepted in libfprint
|
||||
upstream. Proprietary drivers would make it impossible to debug problems in
|
||||
libfprint, as we wouldn't know what the proprietary driver does behind the
|
||||
library's back. The closed source nature of drivers is usually used to hide
|
||||
parts of the hardware setup, such as encryption keys, or protocols, in order
|
||||
to protect the hardware's integrity. Unfortunately, this is only [security through
|
||||
obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity).
|
||||
|
||||
We however encourage potential contributors to take advantage of libfprint's
|
||||
source availability to create such shims to make it easier to reverse-engineer
|
||||
proprietary drivers in order to create new free software drivers, to the extent
|
||||
permitted by local laws.
|
||||
|
||||
## Two-faced-ness
|
||||
|
||||
|
||||
27
NEWS
27
NEWS
@@ -1,6 +1,33 @@
|
||||
This file lists notable changes in each release. For the full history of all
|
||||
changes, see ChangeLog.
|
||||
|
||||
2019-08-08: v1.0 release
|
||||
* Library:
|
||||
- Add guards to the public API and require GLib 2.50
|
||||
- Deprecate print storage API
|
||||
- Better documentation for fp_discover_devs()
|
||||
- Remove unused internal fpi_timeout_cancel_for_dev()
|
||||
- Remove state from fp_img_driver activate handler
|
||||
- Bug fixes related to restarting a failed verification immediately
|
||||
|
||||
* Drivers:
|
||||
- The Elan driver received a lot of bug fixes including a fix for a
|
||||
hang when verifying prints with fprintd, quirks for some devices,
|
||||
a memory leak fix and support for 04f3:0c42
|
||||
- Fix a probable crash in all the AES drivers
|
||||
- Add support for Lenovo Preferred Pro Keyboard (KUF1256) to vfs5011
|
||||
- Prevent hang during enroll process in etes603 driver
|
||||
- Fix possible integer overflow in uru4000
|
||||
- Work-around SELinux AVC warnings when uru4000 driver starts
|
||||
- Remove long-unmaintained and broken fdu2000 driver
|
||||
|
||||
* Tools/Examples:
|
||||
- Fix examples not working due to an overly strict check
|
||||
- Fix crash in GTK demo when there's no supported devices
|
||||
- Disable GTK demo until we have a USB Flatpak portal
|
||||
- Remove sleep() in enroll example which caused a crash in some drivers
|
||||
- Add a simple storage implementation example
|
||||
|
||||
2018-12-14: v0.99.0 release
|
||||
* Library:
|
||||
- All the internal API for device driver writers is now covered by the
|
||||
|
||||
3
code-of-conduct.md
Normal file
3
code-of-conduct.md
Normal file
@@ -0,0 +1,3 @@
|
||||
This project and its community follow the [Freedesktop.org code of conduct]
|
||||
|
||||
[Freedesktop.org code of conduct]: https://www.freedesktop.org/wiki/CodeOfConduct/
|
||||
@@ -404,7 +404,7 @@ static unsigned char list_BD_values[10] = {
|
||||
/*
|
||||
* Adjust the gain according to the histogram data
|
||||
* 0xbd, 0xbe, 0x29 and 0x2A registers are affected
|
||||
* Returns 0 if no problem occured
|
||||
* Returns 0 if no problem occurred
|
||||
* TODO: This is a basic support for gain. It needs testing/tweaking. */
|
||||
static int adjust_gain(unsigned char *buffer, int status)
|
||||
{
|
||||
@@ -412,7 +412,7 @@ static int adjust_gain(unsigned char *buffer, int status)
|
||||
static int pos_list_BE = 0;
|
||||
static int pos_list_BD = 0;
|
||||
|
||||
// This is the first adjustement (we begin acquisition)
|
||||
// This is the first adjustment (we begin acquisition)
|
||||
// We adjust strip_scan_reqs for future strips and capture_reqs that is sent just after this step
|
||||
if (status == GAIN_STATUS_FIRST) {
|
||||
if (buffer[1] > 0x78) { // maximum gain needed
|
||||
@@ -534,7 +534,7 @@ static void restore_gain(void)
|
||||
|
||||
/* capture SM movement:
|
||||
* request and read strip,
|
||||
* jump back to request UNLESS theres no finger, in which case exit SM,
|
||||
* jump back to request UNLESS there's no finger, in which case exit SM,
|
||||
* report lack of finger presence, and move to finger detection */
|
||||
|
||||
enum capture_states {
|
||||
@@ -728,7 +728,7 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat
|
||||
struct fp_img_dev *dev = user_data;
|
||||
|
||||
/* activation on aes1610 seems much more straightforward compared to aes2501 */
|
||||
/* verify theres anything missing here */
|
||||
/* verify there's anything missing here */
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
case WRITE_INIT:
|
||||
fp_dbg("write init");
|
||||
|
||||
@@ -415,7 +415,7 @@ static struct aes_regwrite strip_scan_reqs[] = {
|
||||
/* capture SM movement:
|
||||
* write reqs and read data 1 + 2,
|
||||
* request and read strip,
|
||||
* jump back to request UNLESS theres no finger, in which case exit SM,
|
||||
* jump back to request UNLESS there's no finger, in which case exit SM,
|
||||
* report lack of finger presence, and move to finger detection */
|
||||
|
||||
enum capture_states {
|
||||
|
||||
@@ -109,7 +109,7 @@ enum aes2501_mesure_drive {
|
||||
|
||||
/* Select (1=square | 0=sine) wave drive during measure */
|
||||
#define AES2501_MEASDRV_SQUARE 0x20
|
||||
/* 0 = use mesure drive setting, 1 = when sine wave is selected */
|
||||
/* 0 = use measure drive setting, 1 = when sine wave is selected */
|
||||
#define AES2501_MEASDRV_MEASURE_SQUARE 0x10
|
||||
|
||||
enum aes2501_measure_freq {
|
||||
|
||||
@@ -447,7 +447,7 @@ static void init_read_data_cb(struct libusb_transfer *transfer)
|
||||
}
|
||||
|
||||
/* TODO: use calibration table, datasheet is rather terse on that
|
||||
* need more info for implementaion */
|
||||
* need more info for implementation */
|
||||
static void calibrate_read_data_cb(struct libusb_transfer *transfer)
|
||||
{
|
||||
fpi_ssm *ssm = transfer->user_data;
|
||||
|
||||
@@ -53,12 +53,15 @@ static void write_regv_trf_complete(struct libusb_transfer *transfer)
|
||||
{
|
||||
struct write_regv_data *wdata = transfer->user_data;
|
||||
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
wdata->callback(wdata->imgdev, -EIO, wdata->user_data);
|
||||
else if (transfer->length != transfer->actual_length)
|
||||
g_free(wdata);
|
||||
} else if (transfer->length != transfer->actual_length) {
|
||||
wdata->callback(wdata->imgdev, -EPROTO, wdata->user_data);
|
||||
else
|
||||
g_free(wdata);
|
||||
} else {
|
||||
continue_write_regv(wdata);
|
||||
}
|
||||
|
||||
g_free(transfer->buffer);
|
||||
libusb_free_transfer(transfer);
|
||||
@@ -109,6 +112,7 @@ static void continue_write_regv(struct write_regv_data *wdata)
|
||||
if (offset >= wdata->num_regs) {
|
||||
fp_dbg("all registers written");
|
||||
wdata->callback(wdata->imgdev, 0, wdata->user_data);
|
||||
g_free(wdata);
|
||||
return;
|
||||
}
|
||||
if (wdata->regs[offset].reg)
|
||||
@@ -132,6 +136,7 @@ static void continue_write_regv(struct write_regv_data *wdata)
|
||||
r = do_write_regv(wdata, upper_bound);
|
||||
if (r < 0) {
|
||||
wdata->callback(wdata->imgdev, r, wdata->user_data);
|
||||
g_free(wdata);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -155,8 +160,6 @@ void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
|
||||
wdata->callback = callback;
|
||||
wdata->user_data = user_data;
|
||||
continue_write_regv(wdata);
|
||||
|
||||
g_free(wdata);
|
||||
}
|
||||
|
||||
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,
|
||||
|
||||
@@ -293,23 +293,22 @@ static void elan_process_frame_thirds(unsigned short *raw_frame,
|
||||
static void elan_submit_image(struct fp_img_dev *dev)
|
||||
{
|
||||
struct elan_dev *elandev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
int num_frames;
|
||||
GSList *raw_frames;
|
||||
GSList *frames = NULL;
|
||||
struct fp_img *img;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
|
||||
for (int i = 0; i < ELAN_SKIP_LAST_FRAMES; i++)
|
||||
elandev->frames = g_slist_next(elandev->frames);
|
||||
elandev->num_frames -= ELAN_SKIP_LAST_FRAMES;
|
||||
num_frames = elandev->num_frames - ELAN_SKIP_LAST_FRAMES;
|
||||
raw_frames = g_slist_nth(elandev->frames, ELAN_SKIP_LAST_FRAMES);
|
||||
|
||||
assembling_ctx.frame_width = elandev->frame_width;
|
||||
assembling_ctx.frame_height = elandev->frame_height;
|
||||
assembling_ctx.image_width = elandev->frame_width * 3 / 2;
|
||||
g_slist_foreach(elandev->frames, (GFunc) elandev->process_frame,
|
||||
&frames);
|
||||
fpi_do_movement_estimation(&assembling_ctx, frames,
|
||||
elandev->num_frames);
|
||||
img = fpi_assemble_frames(&assembling_ctx, frames, elandev->num_frames);
|
||||
g_slist_foreach(raw_frames, (GFunc) elandev->process_frame, &frames);
|
||||
fpi_do_movement_estimation(&assembling_ctx, frames, num_frames);
|
||||
img = fpi_assemble_frames(&assembling_ctx, frames, num_frames);
|
||||
|
||||
img->flags |= FP_IMG_PARTIAL;
|
||||
fpi_imgdev_image_captured(dev, img);
|
||||
@@ -425,7 +424,8 @@ elan_run_cmd(fpi_ssm *ssm,
|
||||
elandev->cmd_timeout = cmd_timeout;
|
||||
|
||||
if (cmd->devices != ELAN_ALL_DEV && !(cmd->devices & elandev->dev_type)) {
|
||||
fp_dbg("skipping for this device");
|
||||
fp_dbg("skipping command 0x%x 0x%x for this device (for devices 0x%x but device is 0x%x)",
|
||||
cmd->cmd[0], cmd->cmd[1], cmd->devices, elandev->dev_type);
|
||||
elan_cmd_done(ssm);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1316,7 +1316,7 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
||||
fpi_ssm_next_state(ssm);
|
||||
break;
|
||||
case INIT_SENSOR_REQ:
|
||||
/* In captured traffic, those are splitted. */
|
||||
/* In captured traffic, those are split. */
|
||||
msg_set_regs(dev, 18, REG_MODE_CONTROL, REG_MODE_SLEEP,
|
||||
REG_50, 0x0F, REG_GAIN, 0x04, REG_VRT, 0x08,
|
||||
REG_VRB, 0x0D, REG_VCO_CONTROL, REG_VCO_RT,
|
||||
|
||||
@@ -136,7 +136,7 @@ static unsigned char upeksonly_get_pixel(struct fpi_line_asmbl_ctx *ctx,
|
||||
unsigned char *buf;
|
||||
unsigned offset;
|
||||
|
||||
/* The scans from this device are rolled right by two colums */
|
||||
/* The scans from this device are rolled right by two columns */
|
||||
if (x < ctx->line_width - 2)
|
||||
offset = x + 2;
|
||||
else if ((x > ctx->line_width - 2) && (x < ctx->line_width))
|
||||
@@ -296,12 +296,12 @@ static void row_complete(struct fp_img_dev *dev)
|
||||
sdev->num_blank = 0;
|
||||
} else {
|
||||
sdev->num_blank++;
|
||||
/* Don't consider the scan complete unless theres at least
|
||||
/* Don't consider the scan complete unless there's at least
|
||||
* MIN_ROWS recorded or very long blank read occurred.
|
||||
*
|
||||
* Typical problem spot: one brief touch before starting the
|
||||
* actual scan. Happens most commonly if scan is started
|
||||
* from before the first joint resulting in a gap after the inital touch.
|
||||
* from before the first joint resulting in a gap after the initial touch.
|
||||
*/
|
||||
if (sdev->num_blank > FINGER_REMOVED_THRESHOLD) {
|
||||
sdev->finger_state = FINGER_REMOVED;
|
||||
|
||||
@@ -287,7 +287,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer)
|
||||
fpi_ssm_mark_completed(ssm);
|
||||
break;
|
||||
default:
|
||||
fp_err("Uknown response!\n");
|
||||
fp_err("Unknown response!\n");
|
||||
fpi_ssm_mark_failed(ssm, -EIO);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -668,7 +668,7 @@ static uint32_t do_decode(uint8_t *data, int num_bytes, uint32_t key)
|
||||
data[i] = data[i+1] ^ xorbyte;
|
||||
}
|
||||
|
||||
/* the final byte is implictly zero */
|
||||
/* the final byte is implicitly zero */
|
||||
data[i] = 0;
|
||||
return update_key(key);
|
||||
}
|
||||
|
||||
@@ -577,7 +577,7 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
||||
vdev->need_report = 0;
|
||||
}
|
||||
|
||||
/* Asyncronously enquire an interrupt */
|
||||
/* Asynchronously enquire an interrupt */
|
||||
vdev->transfer = fpi_usb_alloc();
|
||||
vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||
libusb_fill_interrupt_transfer(vdev->transfer, usb_dev, 0x83,
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
/* Minimum image height */
|
||||
#define VFS_IMG_MIN_HEIGHT 200
|
||||
|
||||
/* Scan level thresold */
|
||||
/* Scan level threshold */
|
||||
#define VFS_IMG_SLT_BEGIN 768
|
||||
#define VFS_IMG_SLT_END 64
|
||||
#define VFS_IMG_SLT_LINES 4
|
||||
@@ -641,7 +641,7 @@ static int action_completed(struct fp_img_dev *dev)
|
||||
|
||||
#define offset(x, y) ((x) + ((y) * VFS_FRAME_SIZE))
|
||||
|
||||
/* Screen image to remove noise and find bottom line and height od image */
|
||||
/* Screen image to remove noise and find bottom line and height of image */
|
||||
static void img_screen(struct vfs101_dev *vdev)
|
||||
{
|
||||
int y, x, count, top;
|
||||
@@ -654,7 +654,7 @@ static void img_screen(struct vfs101_dev *vdev)
|
||||
|
||||
/* Image returned from sensor can contain many empty lines,
|
||||
* for remove these lines compare byte 282-283 (scan level information)
|
||||
* with two differents threshold, one for the begin of finger image and
|
||||
* with two different thresholds, one for the begin of finger image and
|
||||
* one for the end. To increase stability of the code use a counter
|
||||
* of lines that satisfy the threshold.
|
||||
*/
|
||||
@@ -700,7 +700,7 @@ static void img_screen(struct vfs101_dev *vdev)
|
||||
|
||||
vdev->height = top - vdev->bottom + 1;
|
||||
|
||||
/* Checkk max height */
|
||||
/* Check max height */
|
||||
if (vdev->height > VFS_IMG_MAX_HEIGHT)
|
||||
vdev->height = VFS_IMG_MAX_HEIGHT;
|
||||
|
||||
@@ -1178,7 +1178,7 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
||||
switch (fpi_ssm_get_cur_state(ssm))
|
||||
{
|
||||
case M_INIT_0_RECV_DIRTY:
|
||||
/* Recv eventualy dirty data */
|
||||
/* Recv eventually dirty data */
|
||||
vdev->ignore_error = TRUE;
|
||||
async_recv(ssm, dev);
|
||||
break;
|
||||
@@ -1463,7 +1463,7 @@ static void dev_deactivate(struct fp_img_dev *dev)
|
||||
/* Reset active state */
|
||||
vdev->active = FALSE;
|
||||
|
||||
/* Handle eventualy existing events */
|
||||
/* Handle eventually existing events */
|
||||
while (vdev->transfer)
|
||||
fp_handle_events();
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ typedef struct {
|
||||
|
||||
unsigned char scan[VFS301_FP_WIDTH];
|
||||
|
||||
/* A offseted, stretched, inverted copy of scan... probably could
|
||||
/* A offsetted, stretched, inverted copy of scan... probably could
|
||||
* serve finger motion speed detection?
|
||||
* Seems to be subdivided to some 10B + 53B + 1B blocks */
|
||||
unsigned char mirror[64];
|
||||
|
||||
@@ -1147,7 +1147,7 @@ static const unsigned char vfs301_24[] = { /* 119 B */
|
||||
*
|
||||
* The contents of PACKET() inside this blob seems to be some kind
|
||||
* of a micro-program, which specifies which columns contain what. LE seems
|
||||
* to be used also here. Not neccessarily is 1 output column described
|
||||
* to be used also here. Not necessarily is 1 output column described
|
||||
* by 1 operation. For example the vfs301_line_t::sum section seems
|
||||
* to perform 2 operations for each column - probably some kind of diff between
|
||||
* input lines?
|
||||
|
||||
@@ -371,7 +371,7 @@ static int process_chunk(struct vfs5011_data *data, int transferred)
|
||||
VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD)) {
|
||||
data->lastline = g_malloc(VFS5011_LINE_SIZE);
|
||||
data->rows = g_slist_prepend(data->rows, data->lastline);
|
||||
g_memmove(data->lastline, linebuf, VFS5011_LINE_SIZE);
|
||||
memmove(data->lastline, linebuf, VFS5011_LINE_SIZE);
|
||||
data->lines_recorded++;
|
||||
if (data->lines_recorded >= data->max_lines_recorded) {
|
||||
fp_dbg("process_chunk: recorded %d lines, finishing",
|
||||
@@ -405,7 +405,7 @@ submit_image(fpi_ssm *ssm,
|
||||
g_slist_free_full(data->rows, g_free);
|
||||
data->rows = NULL;
|
||||
|
||||
fp_dbg("Image captured, commiting");
|
||||
fp_dbg("Image captured, committing");
|
||||
|
||||
fpi_imgdev_image_captured(dev, img);
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ static void median_filter(int *data, int size, int filtersize)
|
||||
i1 = 0;
|
||||
if (i2 >= size)
|
||||
i2 = size-1;
|
||||
g_memmove(sortbuf, data+i1, (i2-i1+1)*sizeof(int));
|
||||
memmove(sortbuf, data+i1, (i2-i1+1)*sizeof(int));
|
||||
g_qsort_with_data(sortbuf, i2-i1+1, sizeof(int), cmpint, NULL);
|
||||
result[i] = sortbuf[(i2-i1+1)/2];
|
||||
}
|
||||
@@ -480,7 +480,7 @@ out:
|
||||
img->height = line_ind;
|
||||
img->width = ctx->line_width;
|
||||
img->flags = FP_IMG_V_FLIPPED;
|
||||
g_memmove(img->data, output, ctx->line_width * line_ind);
|
||||
memmove(img->data, output, ctx->line_width * line_ind);
|
||||
g_free(offsets);
|
||||
g_free(output);
|
||||
return img;
|
||||
|
||||
@@ -387,9 +387,21 @@ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev,
|
||||
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
G_DEBUG_HERE();
|
||||
|
||||
if (dev->state == DEV_STATE_VERIFY_STOPPING) {
|
||||
fp_dbg ("Already stopping verification, returning -EINPROGRESS");
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
if (dev->state == DEV_STATE_INITIALIZED) {
|
||||
if (callback)
|
||||
callback(dev, user_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_ERROR
|
||||
&& dev->state != DEV_STATE_VERIFYING
|
||||
&& dev->state != DEV_STATE_VERIFY_DONE);
|
||||
@@ -511,9 +523,21 @@ API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev,
|
||||
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
|
||||
G_DEBUG_HERE();
|
||||
|
||||
if (dev->state == DEV_STATE_IDENTIFY_STOPPING) {
|
||||
fp_dbg ("Already stopping identification, returning -EINPROGRESS");
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
if (dev->state == DEV_STATE_INITIALIZED) {
|
||||
if (callback)
|
||||
callback(dev, user_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
BUG_ON(dev->state != DEV_STATE_IDENTIFYING
|
||||
&& dev->state != DEV_STATE_IDENTIFY_DONE);
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data,
|
||||
item = list_item->data;
|
||||
out_item = (struct fpi_print_data_item_fp2 *)buf;
|
||||
out_item->length = GUINT32_TO_LE(item->length);
|
||||
/* FIXME: fp_print_data_item->data content is not endianess agnostic */
|
||||
/* FIXME: fp_print_data_item->data content is not endianness agnostic */
|
||||
memcpy(out_item->data, item->data, item->length);
|
||||
buf += sizeof(*out_item);
|
||||
buf += item->length;
|
||||
@@ -236,7 +236,7 @@ static struct fp_print_data *fpi_print_data_from_fp1_data(unsigned char *buf,
|
||||
data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
|
||||
GUINT32_FROM_LE(raw->devtype), raw->data_type);
|
||||
item = fpi_print_data_item_new(print_data_len);
|
||||
/* FIXME: fp_print_data->data content is not endianess agnostic */
|
||||
/* FIXME: fp_print_data->data content is not endianness agnostic */
|
||||
memcpy(item->data, raw->data, print_data_len);
|
||||
data->prints = g_slist_prepend(data->prints, item);
|
||||
|
||||
@@ -272,7 +272,7 @@ static struct fp_print_data *fpi_print_data_from_fp2_data(unsigned char *buf,
|
||||
total_data_len -= item_len;
|
||||
|
||||
item = fpi_print_data_item_new(item_len);
|
||||
/* FIXME: fp_print_data->data content is not endianess agnostic */
|
||||
/* FIXME: fp_print_data->data content is not endianness agnostic */
|
||||
memcpy(item->data, raw_item->data, item_len);
|
||||
data->prints = g_slist_prepend(data->prints, item);
|
||||
|
||||
|
||||
@@ -485,9 +485,15 @@ void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status)
|
||||
*/
|
||||
void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev)
|
||||
{
|
||||
enum fp_imgdev_action action;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
|
||||
switch (imgdev->action) {
|
||||
action = imgdev->action;
|
||||
imgdev->action = IMG_ACTION_NONE;
|
||||
imgdev->action_state = 0;
|
||||
|
||||
switch (action) {
|
||||
case IMG_ACTION_ENROLL:
|
||||
fpi_drvcb_enroll_stopped(FP_DEV(imgdev));
|
||||
break;
|
||||
@@ -504,9 +510,6 @@ void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev)
|
||||
fp_err("unhandled action %d", imgdev->action);
|
||||
break;
|
||||
}
|
||||
|
||||
imgdev->action = IMG_ACTION_NONE;
|
||||
imgdev->action_state = 0;
|
||||
}
|
||||
|
||||
int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev)
|
||||
|
||||
@@ -405,7 +405,7 @@ int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img,
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: space is wasted if we dont hit the max minutiae count. would
|
||||
/* FIXME: space is wasted if we don't hit the max minutiae count. would
|
||||
* be good to make this dynamic. */
|
||||
print = fpi_print_data_new(FP_DEV(imgdev));
|
||||
item = fpi_print_data_item_new(sizeof(struct xyt_struct));
|
||||
|
||||
@@ -149,7 +149,7 @@ static void enroll_stop_cb(struct fp_dev *dev, void *user_data)
|
||||
* or I/O problems.
|
||||
*
|
||||
* The RETRY codes from #fp_enroll_result may be returned from any enroll
|
||||
* stage. These codes indicate that the scan was not succesful in that the
|
||||
* stage. These codes indicate that the scan was not successful in that the
|
||||
* user did not position their finger correctly or similar. When a RETRY code
|
||||
* is returned, the enrollment stage is <emphasis role="strong">not</emphasis> advanced, so the next call
|
||||
* into this function will retry the current stage again. The current stage may
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
project('libfprint', [ 'c', 'cpp' ],
|
||||
version: '0.99.0',
|
||||
version: '1.0',
|
||||
license: 'LGPLv2.1+',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
|
||||
Reference in New Issue
Block a user