mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Compare commits
31 Commits
vincenth/s
...
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 | ||
|
|
4cec28416e | ||
|
|
3b32baccf6 | ||
|
|
16875d7776 | ||
|
|
a9600e23a1 | ||
|
|
a4b6813ebf | ||
|
|
ef90938eb9 | ||
|
|
66891274a7 | ||
|
|
f52276bd06 | ||
|
|
7dce8dbfaa | ||
|
|
3b757ee738 |
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/
|
||||
@@ -27,7 +27,6 @@ private_headers = [
|
||||
'vfs301_proto_fragments.h',
|
||||
'vfs301_proto.h',
|
||||
'vfs5011_proto.h',
|
||||
'synaptics.h',
|
||||
|
||||
# NBIS
|
||||
'morph.h',
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Example fingerprint delete finger program, which delete the right index
|
||||
* finger which has been previously enrolled to disk.
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
|
||||
{
|
||||
struct fp_dscv_dev *ddev = discovered_devs[0];
|
||||
struct fp_driver *drv;
|
||||
if (!ddev)
|
||||
return NULL;
|
||||
|
||||
drv = fp_dscv_dev_get_driver(ddev);
|
||||
printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv));
|
||||
return ddev;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int r = 1;
|
||||
struct fp_dscv_dev *ddev;
|
||||
struct fp_dscv_dev **discovered_devs;
|
||||
struct fp_dev *dev;
|
||||
struct fp_print_data *data;
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
r = fp_init();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
discovered_devs = fp_discover_devs();
|
||||
if (!discovered_devs) {
|
||||
fprintf(stderr, "Could not discover devices\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ddev = discover_device(discovered_devs);
|
||||
if (!ddev) {
|
||||
fprintf(stderr, "No devices detected.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev = fp_dev_open(ddev);
|
||||
fp_dscv_devs_free(discovered_devs);
|
||||
if (!dev) {
|
||||
fprintf(stderr, "Could not open device.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Opened device. Loading previously enrolled right index finger "
|
||||
"data...\n");
|
||||
|
||||
r = fp_print_data_load(dev, RIGHT_INDEX, &data);
|
||||
if (r != 0) {
|
||||
fprintf(stderr, "Failed to load fingerprint, error %d\n", r);
|
||||
fprintf(stderr, "Did you remember to enroll your right index finger "
|
||||
"first?\n");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
printf("Print loaded. delete data in sensor.\n");
|
||||
if(!fp_dev_supports_data_in_sensor(dev))
|
||||
{
|
||||
printf("This driver doesn't support to store data in sensor.\n");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
r = fp_delete_finger(dev, data);
|
||||
fp_print_data_free(data);
|
||||
if (r) {
|
||||
printf("delete finger failed with error %d :(\n", r);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("sensor data deleted. now delete host data");
|
||||
r = fp_print_data_delete(dev, RIGHT_INDEX);
|
||||
if (r < 0) {
|
||||
printf("Delete sensor data successfully but delete host data failed. %d :(\n", r);
|
||||
}
|
||||
}
|
||||
|
||||
out_close:
|
||||
fp_dev_close(dev);
|
||||
out:
|
||||
fp_exit();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
#include "storage.h"
|
||||
|
||||
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
|
||||
{
|
||||
struct fp_dscv_dev *ddev = discovered_devs[0];
|
||||
@@ -142,10 +144,7 @@ int main(void)
|
||||
if (!data)
|
||||
goto out_close;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
r = fp_print_data_save(data, RIGHT_INDEX);
|
||||
#pragma GCC diagnostic pop
|
||||
r = print_data_save(data, RIGHT_INDEX);
|
||||
if (r < 0)
|
||||
fprintf(stderr, "Data save failed, code %d\n", r);
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
examples = [ 'verify_live', 'enroll', 'verify', 'img_capture', 'delete' ]
|
||||
examples = [ 'verify_live', 'enroll', 'verify', 'img_capture' ]
|
||||
foreach example: examples
|
||||
executable(example,
|
||||
example + '.c',
|
||||
dependencies: libfprint_dep,
|
||||
[example + '.c', 'storage.c'],
|
||||
dependencies: [libfprint_dep, glib_dep],
|
||||
include_directories: [
|
||||
root_inc,
|
||||
],
|
||||
|
||||
136
examples/storage.c
Normal file
136
examples/storage.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Trivial storage driver for example programs
|
||||
*
|
||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
#define STORAGE_FILE "test-storage.variant"
|
||||
|
||||
static char *
|
||||
get_print_data_descriptor (struct fp_print_data *data, struct fp_dev *dev, enum fp_finger finger)
|
||||
{
|
||||
gint drv_id;
|
||||
gint devtype;
|
||||
|
||||
if (data) {
|
||||
drv_id = fp_print_data_get_driver_id (data);
|
||||
devtype = fp_print_data_get_devtype (data);
|
||||
} else {
|
||||
drv_id = fp_driver_get_driver_id(fp_dev_get_driver (dev));
|
||||
devtype = fp_dev_get_devtype (dev);
|
||||
}
|
||||
|
||||
return g_strdup_printf("%x/%08x/%x",
|
||||
drv_id,
|
||||
devtype,
|
||||
finger);
|
||||
}
|
||||
|
||||
static GVariantDict*
|
||||
load_data(void)
|
||||
{
|
||||
GVariantDict *res;
|
||||
GVariant *var;
|
||||
gchar *contents = NULL;
|
||||
gssize length = 0;
|
||||
|
||||
if (!g_file_get_contents (STORAGE_FILE, &contents, &length, NULL)) {
|
||||
g_warning ("Error loading storage, assuming it is empty");
|
||||
return g_variant_dict_new(NULL);
|
||||
}
|
||||
|
||||
var = g_variant_new_from_data (G_VARIANT_TYPE_VARDICT, contents, length, FALSE, NULL, NULL);
|
||||
|
||||
res = g_variant_dict_new(var);
|
||||
g_variant_unref(var);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
save_data(GVariant *data)
|
||||
{
|
||||
const gchar *contents = NULL;
|
||||
gsize length;
|
||||
|
||||
length = g_variant_get_size(data);
|
||||
contents = (gchar*) g_variant_get_data (data);
|
||||
|
||||
if (!g_file_set_contents (STORAGE_FILE, contents, length, NULL)) {
|
||||
g_warning ("Error saving storage,!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_variant_ref_sink(data);
|
||||
g_variant_unref(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
print_data_save(struct fp_print_data *fp_data, enum fp_finger finger)
|
||||
{
|
||||
gchar *descr = get_print_data_descriptor (fp_data, NULL, finger);
|
||||
GVariantDict *dict;
|
||||
GVariant *val;
|
||||
guchar *data;
|
||||
gsize size;
|
||||
int res;
|
||||
|
||||
dict = load_data();
|
||||
|
||||
size = fp_print_data_get_data(fp_data, &data);
|
||||
val = g_variant_new_fixed_array (G_VARIANT_TYPE("y"), data, size, 1);
|
||||
g_variant_dict_insert_value (dict, descr, val);
|
||||
|
||||
res = save_data(g_variant_dict_end(dict));
|
||||
g_variant_dict_unref(dict);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct fp_print_data*
|
||||
print_data_load(struct fp_dev *dev, enum fp_finger finger)
|
||||
{
|
||||
gchar *descr = get_print_data_descriptor (NULL, dev, finger);
|
||||
GVariantDict *dict;
|
||||
guchar *stored_data;
|
||||
gsize stored_len;
|
||||
GVariant *val;
|
||||
struct fp_print_data *res = NULL;
|
||||
|
||||
dict = load_data();
|
||||
val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay"));
|
||||
|
||||
if (val) {
|
||||
stored_data = (guchar*) g_variant_get_fixed_array (val, &stored_len, 1);
|
||||
res = fp_print_data_from_data(stored_data, stored_len);
|
||||
|
||||
g_variant_unref(val);
|
||||
}
|
||||
|
||||
g_variant_dict_unref(dict);
|
||||
g_free(descr);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
* Trivial storage driver for example programs
|
||||
*
|
||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,29 +18,10 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _BMKT_INTERNAL_H_
|
||||
#define _BMKT_INTERNAL_H_
|
||||
#ifndef __STORAGE_H
|
||||
#define __STORAGE_H
|
||||
|
||||
#include "bmkt.h"
|
||||
#include "bmkt_message.h"
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "fp_internal.h"
|
||||
int print_data_save(struct fp_print_data *fp_data, enum fp_finger finger);
|
||||
struct fp_print_data* print_data_load(struct fp_dev *dev, enum fp_finger finger);
|
||||
|
||||
uint32_t extract32(const uint8_t *buf, int *offset);
|
||||
uint16_t extract16(const uint8_t *buf, int *offset);
|
||||
uint8_t extract8(const uint8_t *buf, int *offset);
|
||||
void print_buffer(uint8_t *buf, int len);
|
||||
|
||||
|
||||
#define bmkt_dbg_log fp_dbg
|
||||
#define bmkt_info_log fp_info
|
||||
#define bmkt_warn_log fp_warn
|
||||
#define bmkt_err_log fp_err
|
||||
|
||||
void bmkt_op_next_state(bmkt_sensor_t *sensor);
|
||||
|
||||
#endif /* _BMKT_INTERNAL_H_ */
|
||||
#endif /* __STORAGE_H */
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
#include "storage.h"
|
||||
|
||||
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
|
||||
{
|
||||
struct fp_dscv_dev *ddev = discovered_devs[0];
|
||||
@@ -117,11 +119,8 @@ int main(void)
|
||||
printf("Opened device. Loading previously enrolled right index finger "
|
||||
"data...\n");
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
r = fp_print_data_load(dev, RIGHT_INDEX, &data);
|
||||
#pragma GCC diagnostic pop
|
||||
if (r != 0) {
|
||||
data = print_data_load(dev, RIGHT_INDEX);
|
||||
if (!data) {
|
||||
fprintf(stderr, "Failed to load fingerprint, error %d\n", r);
|
||||
fprintf(stderr, "Did you remember to enroll your right index finger "
|
||||
"first?\n");
|
||||
|
||||
@@ -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");
|
||||
@@ -749,7 +749,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
||||
fpi_ssm_free(ssm);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct aes1610_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
||||
|
||||
@@ -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 {
|
||||
@@ -792,7 +792,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
||||
fpi_ssm_free(ssm);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
||||
|
||||
@@ -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;
|
||||
@@ -541,7 +541,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
||||
fpi_ssm_free(ssm);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
||||
ACTIVATE_NUM_STATES, dev);
|
||||
|
||||
@@ -137,7 +137,7 @@ static void init_reqs_cb(struct fp_img_dev *dev, int result, void *user_data)
|
||||
do_capture(dev);
|
||||
}
|
||||
|
||||
int aes3k_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
int aes3k_dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct aes3k_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
aes_write_regv(dev, aesdev->init_reqs, aesdev->init_reqs_len, init_reqs_cb, NULL);
|
||||
|
||||
@@ -52,7 +52,7 @@ struct aes3k_dev {
|
||||
};
|
||||
|
||||
|
||||
int aes3k_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
||||
int aes3k_dev_activate(struct fp_img_dev *dev);
|
||||
void aes3k_dev_deactivate(struct fp_img_dev *dev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -589,7 +589,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
||||
start_finger_detection(dev);
|
||||
}
|
||||
|
||||
int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
int aesX660_dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
||||
ACTIVATE_NUM_STATES, dev);
|
||||
|
||||
@@ -116,7 +116,7 @@ static const unsigned char calibrate_cmd[] = {
|
||||
0x06,
|
||||
};
|
||||
|
||||
int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
||||
int aesX660_dev_activate(struct fp_img_dev *dev);
|
||||
void aesX660_dev_deactivate(struct fp_img_dev *dev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@ enum {
|
||||
AES2501_ID = 4,
|
||||
UPEKTC_ID = 5,
|
||||
AES1610_ID = 6,
|
||||
FDU2000_ID = 7,
|
||||
/* FDU2000_ID = 7, */
|
||||
VCOM5S_ID = 8,
|
||||
UPEKSONLY_ID = 9,
|
||||
VFS101_ID = 10,
|
||||
@@ -42,7 +42,6 @@ enum {
|
||||
VFS5011_ID = 19,
|
||||
VFS0050_ID = 20,
|
||||
ELAN_ID = 21,
|
||||
SYNAPTICS_ID = 22,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -874,7 +874,7 @@ static void dev_deinit(struct fp_img_dev *dev)
|
||||
fpi_imgdev_close_complete(dev);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
G_DEBUG_HERE();
|
||||
elan_activate(dev);
|
||||
|
||||
@@ -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,
|
||||
@@ -1390,19 +1390,13 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
||||
fpi_ssm_free(ssm);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *idev)
|
||||
{
|
||||
struct etes603_dev *dev = FP_INSTANCE_DATA(FP_DEV(idev));
|
||||
fpi_ssm *ssm;
|
||||
|
||||
g_assert(dev);
|
||||
|
||||
if (state != IMGDEV_STATE_AWAIT_FINGER_ON) {
|
||||
fp_err("The driver is in an unexpected state: %d.", state);
|
||||
fpi_imgdev_activate_complete(idev, 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reset info and data */
|
||||
dev->is_active = TRUE;
|
||||
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
/*
|
||||
* Secugen FDU2000 driver for libfprint
|
||||
* Copyright (C) 2007 Gustavo Chain <g@0xff.cl>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "fdu2000"
|
||||
|
||||
#include "drivers_api.h"
|
||||
|
||||
#ifndef HAVE_MEMMEM
|
||||
gpointer
|
||||
memmem(const gpointer haystack, size_t haystack_len, const gpointer needle, size_t needle_len) {
|
||||
const gchar *begin;
|
||||
const char *const last_possible = (const char *) haystack + haystack_len - needle_len;
|
||||
|
||||
/* The first occurrence of the empty string is deemed to occur at
|
||||
* the beginning of the string. */
|
||||
if (needle_len == 0)
|
||||
return (void *) haystack;
|
||||
|
||||
/* Sanity check, otherwise the loop might search through the whole
|
||||
* memory. */
|
||||
if (haystack_len < needle_len)
|
||||
return NULL;
|
||||
|
||||
for (begin = (const char *) haystack; begin <= last_possible; ++begin)
|
||||
if (begin[0] == ((const char *) needle)[0] &&
|
||||
!memcmp((const void *) &begin[1],
|
||||
(const void *) ((const char *) needle + 1),
|
||||
needle_len - 1))
|
||||
return (void *) begin;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* HAVE_MEMMEM */
|
||||
|
||||
#define EP_IMAGE ( 0x02 | LIBUSB_ENDPOINT_IN )
|
||||
#define EP_REPLY ( 0x01 | LIBUSB_ENDPOINT_IN )
|
||||
#define EP_CMD ( 0x01 | LIBUSB_ENDPOINT_OUT )
|
||||
#define BULK_TIMEOUT 200
|
||||
|
||||
/* fdu_req[] index */
|
||||
typedef enum {
|
||||
CAPTURE_READY,
|
||||
CAPTURE_READ,
|
||||
CAPTURE_END,
|
||||
LED_OFF,
|
||||
LED_ON
|
||||
} req_index;
|
||||
|
||||
|
||||
#define CMD_LEN 2
|
||||
#define ACK_LEN 8
|
||||
static const struct fdu2000_req {
|
||||
const gchar cmd[CMD_LEN]; // Command to send
|
||||
const gchar ack[ACK_LEN]; // Expected ACK
|
||||
const guint ack_len; // ACK has variable length
|
||||
} fdu_req[] = {
|
||||
/* Capture */
|
||||
{
|
||||
.cmd = { 0x00, 0x04 },
|
||||
.ack = { 0x00, 0x04, 0x01, 0x01 },
|
||||
.ack_len = 4
|
||||
},
|
||||
|
||||
{
|
||||
.cmd = { 0x00, 0x01 },
|
||||
.ack = { 0x00, 0x01, 0x01, 0x01 },
|
||||
.ack_len = 4
|
||||
},
|
||||
|
||||
{
|
||||
.cmd = { 0x00, 0x05 },
|
||||
.ack = { 0x00, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
.ack_len = 8
|
||||
},
|
||||
|
||||
/* Led */
|
||||
{
|
||||
.cmd = { 0x05, 0x00 },
|
||||
.ack = {},
|
||||
.ack_len = 0
|
||||
},
|
||||
|
||||
{
|
||||
.cmd = { 0x05, 0x01 },
|
||||
.ack = {},
|
||||
.ack_len = 0
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Write a command and verify reponse
|
||||
*/
|
||||
static gint
|
||||
bulk_write_safe(libusb_dev_handle *dev, req_index rIndex) {
|
||||
|
||||
gchar reponse[ACK_LEN];
|
||||
gint r;
|
||||
gchar *cmd = (gchar *)fdu_req[rIndex].cmd;
|
||||
gchar *ack = (gchar *)fdu_req[rIndex].ack;
|
||||
gint ack_len = fdu_req[rIndex].ack_len;
|
||||
struct libusb_bulk_transfer wrmsg = {
|
||||
.endpoint = EP_CMD,
|
||||
.data = cmd,
|
||||
.length = sizeof(cmd),
|
||||
};
|
||||
struct libusb_bulk_transfer readmsg = {
|
||||
.endpoint = EP_REPLY,
|
||||
.data = reponse,
|
||||
.length = sizeof(reponse),
|
||||
};
|
||||
int trf;
|
||||
|
||||
r = libusb_bulk_transfer(dev, &wrmsg, &trf, BULK_TIMEOUT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ack_len == 0)
|
||||
return 0;
|
||||
|
||||
/* Check reply from FP */
|
||||
r = libusb_bulk_transfer(dev, &readmsg, &trf, BULK_TIMEOUT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!strncmp(ack, reponse, ack_len))
|
||||
return 0;
|
||||
|
||||
fp_err("Expected different ACK from dev");
|
||||
return 1; /* Error */
|
||||
}
|
||||
|
||||
static gint
|
||||
capture(struct fp_img_dev *dev, gboolean unconditional,
|
||||
struct fp_img **ret)
|
||||
{
|
||||
#define RAW_IMAGE_WIDTH 398
|
||||
#define RAW_IMAGE_HEIGTH 301
|
||||
#define RAW_IMAGE_SIZE (RAW_IMAGE_WIDTH * RAW_IMAGE_HEIGTH)
|
||||
|
||||
struct fp_img *img = NULL;
|
||||
int bytes, r;
|
||||
const gchar SOF[] = { 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0c, 0x07 }; // Start of frame
|
||||
const gchar SOL[] = { 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0b, 0x06 }; // Start of line + { L L } (L: Line num) (8 nibbles)
|
||||
gchar *buffer = g_malloc0(RAW_IMAGE_SIZE * 6);
|
||||
gchar *image;
|
||||
gchar *p;
|
||||
guint offset;
|
||||
struct libusb_bulk_transfer msg = {
|
||||
.endpoint = EP_IMAGE,
|
||||
.data = buffer,
|
||||
.length = RAW_IMAGE_SIZE * 6,
|
||||
};
|
||||
|
||||
image = g_malloc0(RAW_IMAGE_SIZE);
|
||||
|
||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_ON))) {
|
||||
fp_err("Command: LED_ON");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_READY))) {
|
||||
fp_err("Command: CAPTURE_READY");
|
||||
goto out;
|
||||
}
|
||||
|
||||
read:
|
||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_READ))) {
|
||||
fp_err("Command: CAPTURE_READ");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Now we are ready to read from dev */
|
||||
|
||||
r = libusb_bulk_transfer(fpi_dev_get_usb_dev(FP_DEV(dev)), &msg, &bytes, BULK_TIMEOUT * 10);
|
||||
if (r < 0 || bytes < 1)
|
||||
goto read;
|
||||
|
||||
/*
|
||||
* Find SOF (start of line)
|
||||
*/
|
||||
p = memmem(buffer, RAW_IMAGE_SIZE * 6,
|
||||
(const gpointer)SOF, sizeof SOF);
|
||||
fp_dbg("Read %d byte/s from dev", bytes);
|
||||
if (!p)
|
||||
goto out;
|
||||
|
||||
p += sizeof SOF;
|
||||
|
||||
int i = 0;
|
||||
bytes = 0;
|
||||
while(p) {
|
||||
if ( i >= RAW_IMAGE_HEIGTH )
|
||||
break;
|
||||
|
||||
offset = p - buffer;
|
||||
p = memmem(p, (RAW_IMAGE_SIZE * 6) - (offset),
|
||||
(const gpointer)SOL, sizeof SOL);
|
||||
if (p) {
|
||||
p += sizeof SOL + 4;
|
||||
int j;
|
||||
for (j = 0; j < RAW_IMAGE_WIDTH; j++) {
|
||||
/*
|
||||
* Convert from 4 to 8 bits
|
||||
* The SECUGEN-FDU2000 has 4 lines of data, so we need to join 2 bytes into 1
|
||||
*/
|
||||
*(image + bytes + j) = *(p + (j * 2) + 0) << 4 & 0xf0;
|
||||
*(image + bytes + j) |= *(p + (j * 2) + 1) & 0x0f;
|
||||
}
|
||||
p += RAW_IMAGE_WIDTH * 2;
|
||||
bytes += RAW_IMAGE_WIDTH;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END))) {
|
||||
fp_err("Command: CAPTURE_END");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_OFF))) {
|
||||
fp_err("Command: LED_OFF");
|
||||
goto out;
|
||||
}
|
||||
|
||||
img = fpi_img_new_for_imgdev(dev);
|
||||
memcpy(img->data, image, RAW_IMAGE_SIZE);
|
||||
img->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED;
|
||||
*ret = img;
|
||||
|
||||
out:
|
||||
g_free(buffer);
|
||||
g_free(image);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static
|
||||
gint dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
||||
{
|
||||
gint r;
|
||||
//if ( (r = usb_set_configuration(fpi_dev_get_usb_dev(FP_DEV(dev)), 1)) < 0 )
|
||||
// goto out;
|
||||
|
||||
if ( (r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0)) < 0 ) {
|
||||
fp_err("could not claim interface 0: %s", libusb_error_name(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
//if ( (r = usb_set_altinterface(fpi_dev_get_usb_dev(FP_DEV(dev)), 1)) < 0 )
|
||||
// goto out;
|
||||
|
||||
//if ( (r = usb_clear_halt(fpi_dev_get_usb_dev(FP_DEV(dev)), EP_CMD)) < 0 )
|
||||
// goto out;
|
||||
|
||||
/* Make sure sensor mode is not capture_{ready|read} */
|
||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END))) {
|
||||
fp_err("Command: CAPTURE_END");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_OFF))) {
|
||||
fp_err("Command: LED_OFF");
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
fp_err("could not init dev");
|
||||
return r;
|
||||
}
|
||||
|
||||
static
|
||||
void dev_exit(struct fp_img_dev *dev)
|
||||
{
|
||||
if (bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END))
|
||||
fp_err("Command: CAPTURE_END");
|
||||
|
||||
libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0);
|
||||
}
|
||||
|
||||
static const struct usb_id id_table[] = {
|
||||
{ .vendor = 0x1162, .product = 0x0300 },
|
||||
{ 0, 0, 0, },
|
||||
};
|
||||
|
||||
struct fp_img_driver fdu2000_driver = {
|
||||
.driver = {
|
||||
.id = FDU2000_ID,
|
||||
.name = FP_COMPONENT,
|
||||
.full_name = "Secugen FDU 2000",
|
||||
.id_table = id_table,
|
||||
.scan_type = FP_SCAN_TYPE_PRESS,
|
||||
},
|
||||
.img_height = RAW_IMAGE_HEIGTH,
|
||||
.img_width = RAW_IMAGE_WIDTH,
|
||||
.bz3_threshold = 23,
|
||||
|
||||
.init = dev_init,
|
||||
.exit = dev_exit,
|
||||
.capture = capture,
|
||||
};
|
||||
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "bmkt_internal.h"
|
||||
#include "bmkt_message.h"
|
||||
#include "sensor.h"
|
||||
|
||||
struct bmkt_ctx
|
||||
{
|
||||
bmkt_sensor_t sensor;
|
||||
};
|
||||
|
||||
bmkt_ctx_t g_ctx;
|
||||
|
||||
int bmkt_init(bmkt_ctx_t **ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
memset(&g_ctx, 0, sizeof(bmkt_ctx_t));
|
||||
*ctx = &g_ctx;
|
||||
|
||||
bmkt_dbg_log("%s: context size: %ld", __func__, sizeof(bmkt_ctx_t));
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
void bmkt_exit(bmkt_ctx_t *ctx)
|
||||
{
|
||||
|
||||
if (ctx == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int bmkt_open(bmkt_ctx_t *ctx, bmkt_sensor_t **sensor,
|
||||
bmkt_general_error_cb_t err_cb, void *err_cb_ctx, libusb_device_handle *usb_handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL || sensor == NULL)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*sensor = &ctx->sensor;
|
||||
|
||||
memset(*sensor, 0, sizeof(bmkt_sensor_t));
|
||||
|
||||
(*sensor)->usb_xport.handle = usb_handle;
|
||||
|
||||
ret = bmkt_sensor_open(*sensor, err_cb, err_cb_ctx);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_init_fps(bmkt_sensor_t *sensor)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *resp_buf;
|
||||
int resp_len;
|
||||
bmkt_response_t resp;
|
||||
|
||||
if (sensor->sensor_state != BMKT_SENSOR_STATE_UNINIT)
|
||||
{
|
||||
//sensor is already initialized
|
||||
return BMKT_OPERATION_DENIED;
|
||||
}
|
||||
ret = bmkt_sensor_send_message_sync(sensor, BMKT_CMD_FPS_INIT, 0, NULL, &resp_buf, &resp_len, &resp);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (resp.result != BMKT_SUCCESS)
|
||||
{
|
||||
return resp.result;
|
||||
}
|
||||
|
||||
return bmkt_sensor_init_fps(sensor);
|
||||
}
|
||||
|
||||
int bmkt_close(bmkt_sensor_t *sensor)
|
||||
{
|
||||
if (sensor == NULL)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return bmkt_sensor_close(sensor);
|
||||
}
|
||||
|
||||
|
||||
int bmkt_delete_enrolled_user(bmkt_sensor_t *sensor, uint8_t finger_id, const char *user_id, uint32_t user_id_len,
|
||||
bmkt_resp_cb_t resp_cb, void *cb_ctx)
|
||||
{
|
||||
int ret;
|
||||
uint8_t payload[BMKT_MAX_USER_ID_LEN + sizeof(finger_id)];
|
||||
uint8_t payload_len;
|
||||
|
||||
if (sensor == NULL)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (user_id_len > BMKT_MAX_USER_ID_LEN)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
memset(payload, 0, sizeof(payload));
|
||||
payload_len = user_id_len + sizeof(finger_id);
|
||||
payload[0] = finger_id;
|
||||
memcpy(&payload[1], user_id, user_id_len);
|
||||
|
||||
ret = bmkt_sensor_send_message(sensor, BMKT_CMD_DEL_USER_FP, payload_len, payload, resp_cb, cb_ctx);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_enroll(bmkt_sensor_t *sensor, const uint8_t *user_id, uint32_t user_id_len,
|
||||
uint8_t finger_id, bmkt_resp_cb_t resp_cb, void *cb_ctx)
|
||||
{
|
||||
int ret = BMKT_GENERAL_ERROR;
|
||||
/* Payload data for enroll_user [1 byte<backup option> 1 byte<finger Id> maximum length: 100 bytes]*/
|
||||
uint8_t payload[BMKT_MAX_USER_ID_LEN + 2];
|
||||
uint8_t payload_len = 0;
|
||||
/* Backup options is not supported for Prometheus. */
|
||||
uint8_t backup_opt = 0;
|
||||
|
||||
if (sensor == NULL || user_id == NULL)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (user_id_len > BMKT_MAX_USER_ID_LEN)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
payload_len = user_id_len + 2;
|
||||
payload[0] = backup_opt;
|
||||
payload[1] = finger_id;
|
||||
memcpy(&payload[2], user_id, user_id_len);
|
||||
|
||||
ret = bmkt_sensor_send_message(sensor, BMKT_CMD_ENROLL_USER, payload_len, payload, resp_cb, cb_ctx);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int bmkt_verify(bmkt_sensor_t *sensor, bmkt_user_id_t *user,
|
||||
bmkt_resp_cb_t resp_cb, void *cb_ctx)
|
||||
{
|
||||
int ret;
|
||||
uint8_t payload[BMKT_MAX_USER_ID_LEN + 1];
|
||||
uint8_t payload_len;
|
||||
|
||||
if (sensor == NULL || user == NULL || user->user_id == NULL)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (user->user_id_len == 0 || user->user_id_len > BMKT_MAX_USER_ID_LEN)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
payload_len = user->user_id_len;
|
||||
memset(payload, 0, sizeof(payload));
|
||||
memcpy(&payload[0], user->user_id, user->user_id_len);
|
||||
|
||||
ret = bmkt_sensor_send_message(sensor, BMKT_CMD_VERIFY_USER, payload_len, payload, resp_cb,
|
||||
cb_ctx);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
void bmkt_op_set_state(bmkt_sensor_t* sensor, bmkt_op_state_t state)
|
||||
{
|
||||
sensor->op_state = state;
|
||||
}
|
||||
|
||||
void bmkt_op_sm(bmkt_sensor_t *sensor)
|
||||
{
|
||||
int ret;
|
||||
int len = 0;
|
||||
bmkt_dbg_log("bmkt_op_sm state = %d", sensor->op_state);
|
||||
switch(sensor->op_state)
|
||||
{
|
||||
case BMKT_OP_STATE_GET_RESP:
|
||||
ret = usb_receive_resp_async(&sensor->usb_xport, &len);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("bmkt_op_sm: usb_receive_resp_async failed %d", ret);
|
||||
}
|
||||
break;
|
||||
case BMKT_OP_STATE_WAIT_INTERRUPT:
|
||||
ret = usb_check_interrupt(&sensor->usb_xport);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("bmkt_op_sm: check_interrupt failed %d", ret);
|
||||
}
|
||||
break;
|
||||
case BMKT_OP_STATE_SEND_ASYNC:
|
||||
ret = bmkt_sensor_send_async_read_command(sensor);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("bmkt_op_sm: bmkt_sensor_send_async_read_command failed %d", ret);
|
||||
}
|
||||
break;
|
||||
case BMKT_OP_STATE_COMPLETE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bmkt_op_next_state(bmkt_sensor_t* sensor)
|
||||
{
|
||||
if(sensor->op_state != BMKT_OP_STATE_COMPLETE)
|
||||
sensor->op_state = (sensor->op_state + 1) % BMKT_OP_STATE_COMPLETE;
|
||||
bmkt_op_sm(sensor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,452 +0,0 @@
|
||||
/*
|
||||
* Synaptics MiS Fingerprint Sensor Interface
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _BMKT_H_
|
||||
#define _BMKT_H_
|
||||
|
||||
/**< User ID maximum length allowed */
|
||||
#define BMKT_MAX_USER_ID_LEN 100
|
||||
/**< Software Part Number length */
|
||||
#define BMKT_PART_NUM_LEN 10
|
||||
/**< Software supplier identification length */
|
||||
#define BMKT_SUPPLIER_ID_LEN 2
|
||||
|
||||
/**< Maximum namber of templates for storing in internal flash of the fingerprint sensor */
|
||||
#define BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH 15
|
||||
|
||||
#include <stdint.h>
|
||||
#include "libusb-1.0/libusb.h"
|
||||
#include "bmkt_response.h"
|
||||
|
||||
/*!
|
||||
*******************************************************************************
|
||||
** Type definition for result
|
||||
*/
|
||||
/** No error; Operation successfully completed. */
|
||||
#define BMKT_SUCCESS 0
|
||||
/** Fingerprint system not initialized */
|
||||
#define BMKT_FP_SYSTEM_NOT_INITIALIZED 101
|
||||
/** Fingerprint system busy performing another operation */
|
||||
#define BMKT_FP_SYSTEM_BUSY 102
|
||||
/** Operation not allowed */
|
||||
#define BMKT_OPERATION_DENIED 103
|
||||
/** System ran out of memory while performing operation */
|
||||
#define BMKT_OUT_OF_MEMORY 104
|
||||
/** Corrupt message, CRC check fail or truncated message */
|
||||
#define BMKT_CORRUPT_MESSAGE 110
|
||||
/** One of the command parameters is outside the range of valid values */
|
||||
#define BMKT_INVALID_PARAM 111
|
||||
/** Unrecognized message or message with invalid message ID */
|
||||
#define BMKT_UNRECOGNIZED_MESSAGE 112
|
||||
/** Operation time out */
|
||||
#define BMKT_OP_TIME_OUT 113
|
||||
/** General error – cause of error cannot be determined */
|
||||
#define BMKT_GENERAL_ERROR 114
|
||||
|
||||
#define BMKT_SET_SECURITY_LEVEL_FAIL 120
|
||||
#define BMKT_GET_SECURITY_LEVEL_FAIL 121
|
||||
|
||||
/** Fingerprint sensor reset while operation was being performed */
|
||||
#define BMKT_SENSOR_RESET 201
|
||||
/** Fingerprint sensor malfunctioned */
|
||||
#define BMKT_SENSOR_MALFUNCTION 202
|
||||
/** Fingerprint sensor cannot be accessed despite repeated attempts */
|
||||
#define BMKT_SENSOR_TAMPERED 203
|
||||
/**
|
||||
* BMKT_SENSOR_NOT_INIT:
|
||||
* Fingerprint sensor module not initialized yet – not ready for use
|
||||
* (different from error code 101 which indicates that the entire system
|
||||
* has not been initialized)
|
||||
*/
|
||||
#define BMKT_SENSOR_NOT_INIT 204
|
||||
/** Number of re-pairing operations exceeded limit or re-pairing has been disabled */
|
||||
#define BMKT_OWNERSHIP_RESET_MAX_EXCEEDED 205
|
||||
/**
|
||||
* BMKT_SENSOR_STIMULUS_ERROR:
|
||||
* There is a finger or debris on the sensor that needs to be removed
|
||||
* before issuing this command
|
||||
*/
|
||||
#define BMKT_SENSOR_STIMULUS_ERROR 213
|
||||
/**
|
||||
* BMKT_CORRUPT_TEMPLATE_DATA:
|
||||
* One of the fingerprint templates stored on flash is corrupt.
|
||||
* This error code is returned in case of failure in finding a fingerprint match
|
||||
* during identify or verify operations while also detecting that one or more
|
||||
* fingerprint templates stored on the flash has become corrupted
|
||||
*/
|
||||
#define BMKT_CORRUPT_TEMPLATE_DATA 300
|
||||
/** Failed to extract features from fingerprint image acquired by sensor */
|
||||
#define BMKT_FEATURE_EXTRACT_FAIL 301
|
||||
/** Failed to generate fingerprint template */
|
||||
#define BMKT_ENROLL_FAIL 302
|
||||
/** Specified finger already enrolled for this user */
|
||||
#define BMKT_ENROLLMENT_EXISTS 303
|
||||
/** Invalid fingerprint image */
|
||||
#define BMKT_INVALID_FP_IMAGE 304
|
||||
/** No matching user fingerprint template found in database */
|
||||
#define BMKT_FP_NO_MATCH 404
|
||||
/** Fingerprint database is full */
|
||||
#define BMKT_FP_DATABASE_FULL 501
|
||||
/** Fingerprint database is empty */
|
||||
#define BMKT_FP_DATABASE_EMPTY 502
|
||||
/** Cannot access fingerprint database */
|
||||
#define BMKT_FP_DATABASE_ACCESS_FAIL 503
|
||||
/** Fingerprint template record does not exist */
|
||||
#define BMKT_FP_DATABASE_NO_RECORD_EXISTS 504
|
||||
/** Failed to read/write system parameters stored on flash */
|
||||
#define BMKT_FP_PARAM_ACCESS_FAIL 505
|
||||
/** Fingerprint is a spoof */
|
||||
#define BMKT_FP_SPOOF_ALERT 801
|
||||
/** Anti-spoof module failure */
|
||||
#define BMKT_ANTI_SPOOF_MODULE_FAIL 802
|
||||
|
||||
#define BMKT_CORRUPT_UPDATE_IMAGE 901
|
||||
#define BMKT_SYSTEM_UPDATE_FAIL 902
|
||||
|
||||
#define BMKT_EVENT_NOT_SET 1000
|
||||
#define BMKT_SENSOR_NOT_READY 1001
|
||||
#define BMKT_TIMEOUT 1002
|
||||
#define BMKT_SENSOR_RESPONSE_PENDING 1003
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* bmkt_mode:
|
||||
* Fingerprint system operational mode values level 1
|
||||
*/
|
||||
typedef enum bmkt_mode
|
||||
{
|
||||
BMKT_STATE_UNINIT = 0xFF,
|
||||
BMKT_STATE_IDLE = 0x00,
|
||||
BMKT_STATE_ENROLL = 0x10,
|
||||
BMKT_STATE_IDENTIFY = 0x20,
|
||||
BMKT_STATE_VERIFY = 0x30,
|
||||
BMKT_STATE_DB_OPS = 0x40,
|
||||
BMKT_STATE_SYS_TEST = 0x50,
|
||||
BMKT_STATE_SYS_OPS = 0x60,
|
||||
} bmkt_mode_t;
|
||||
|
||||
/**
|
||||
* bmkt_mode_level2:
|
||||
* Fingerprint system operational mode values level 2
|
||||
*/
|
||||
typedef enum bmkt_mode_level2
|
||||
{
|
||||
BMKT_STATE_L2_IDLE = 0x00,
|
||||
BMKT_STATE_L2_STARTING = 0x11,
|
||||
BMKT_STATE_L2_WAITING_FOR_FINGER = 0x12,
|
||||
BMKT_STATE_L2_CAPTURE_IMAGE = 0x13,
|
||||
BMKT_STATE_L2_CAPTURE_COMPLETE = 0x14,
|
||||
BMKT_STATE_L2_EXTRACT_FEATURE = 0x15,
|
||||
BMKT_STATE_L2_CREATE_TEMPLATE = 0x16,
|
||||
BMKT_STATE_L2_READING_FROM_FLASH = 0x17,
|
||||
BMKT_STATE_L2_WRITING_TO_FLASH = 0x18,
|
||||
BMKT_STATE_L2_FINISHING = 0x19,
|
||||
BMKT_STATE_L2_CANCELING_OP = 0x20,
|
||||
BMKT_STATE_L2_MATCHING = 0x21,
|
||||
BMKT_STATE_L2_TRANSMITTING_RESPONSE = 0x22,
|
||||
BMKT_STATE_L2_READY_POWER_DOWN = 0xF0,
|
||||
} bmkt_mode_level2_t;
|
||||
|
||||
/**
|
||||
* bmkt_transport_type:
|
||||
* Fingerprint system transport types
|
||||
*/
|
||||
typedef enum bmkt_transport_type
|
||||
{
|
||||
BMKT_TRANSPORT_TYPE_USB = 0,
|
||||
} bmkt_transport_type_t;
|
||||
|
||||
/**
|
||||
* bmkt_usb_config:
|
||||
* Structure represcontainingenting USB configuration details
|
||||
*/
|
||||
typedef struct bmkt_usb_config
|
||||
{
|
||||
int product_id; /**< USB device product ID */
|
||||
} bmkt_usb_config_t;
|
||||
|
||||
/**
|
||||
* bmkt_transport_config_t:
|
||||
* Union containing transport configuration details
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
bmkt_usb_config_t usb_config;
|
||||
} bmkt_transport_config_t;
|
||||
|
||||
/**
|
||||
* bmkt_sensor_desc_t:
|
||||
* Structure containing fingerprint system description
|
||||
*/
|
||||
typedef struct bmkt_sensor_desc
|
||||
{
|
||||
int product_id;
|
||||
int flags;
|
||||
} bmkt_sensor_desc_t;
|
||||
|
||||
/**
|
||||
* bmkt_finger_state_t:
|
||||
* Finger state representation values.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
BMKT_FINGER_STATE_UNKNOWN = 0,
|
||||
BMKT_FINGER_STATE_ON_SENSOR,
|
||||
BMKT_FINGER_STATE_NOT_ON_SENSOR,
|
||||
} bmkt_finger_state_t;
|
||||
|
||||
/**
|
||||
* bmkt_finger_event_t:
|
||||
* Structure containing finger state
|
||||
*/
|
||||
typedef struct bmkt_finger_event
|
||||
{
|
||||
bmkt_finger_state_t finger_state;
|
||||
} bmkt_finger_event_t;
|
||||
|
||||
typedef struct bmkt_user_id
|
||||
{
|
||||
uint8_t user_id_len;
|
||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN];
|
||||
} bmkt_user_id_t;
|
||||
|
||||
typedef struct bmkt_ctx bmkt_ctx_t;
|
||||
typedef struct bmkt_sensor bmkt_sensor_t;
|
||||
typedef struct bmkt_sensor_desc bmkt_sensor_desc_t;
|
||||
typedef struct bmkt_event bmkt_event_t;
|
||||
|
||||
typedef int (*bmkt_resp_cb_t)(bmkt_response_t *resp, void *cb_ctx);
|
||||
typedef int (*bmkt_event_cb_t)(bmkt_finger_event_t *event, void *cb_ctx);
|
||||
typedef int (*bmkt_general_error_cb_t)(uint16_t error, void *cb_ctx);
|
||||
|
||||
/**
|
||||
* bmkt_init:
|
||||
* @brief Initialize the bmkt library.
|
||||
*
|
||||
* @param[out] ctx A double pointer to return the created library module context pointer.
|
||||
*
|
||||
* @return BMKT_SUCCESS
|
||||
* BMKT_INVALID_PARAM
|
||||
*
|
||||
* The bmkt_init function must be invoked to intialize the bmkt library before calling other functions.
|
||||
* The library module context pointer is returned, which must be passed to all other library interface functions.
|
||||
*/
|
||||
int
|
||||
bmkt_init(
|
||||
bmkt_ctx_t ** ctx);
|
||||
|
||||
/**
|
||||
* bmkt_exit:
|
||||
* @brief Uninitialize the bmkt library.
|
||||
*
|
||||
* @param[in] ctx Context pointer created by bmkt_init.
|
||||
*
|
||||
* @return none
|
||||
*
|
||||
* The bmkt_exit function must be invoked when the module is no longer needed.
|
||||
*/
|
||||
|
||||
void
|
||||
bmkt_exit(
|
||||
bmkt_ctx_t * ctx);
|
||||
|
||||
/**
|
||||
* bmkt_open:
|
||||
* @brief Open the specified sensor module.
|
||||
*
|
||||
* @param[in] ctx Context pointer created by bmkt_init.
|
||||
* @param[out] sensor A double pointer to return the created sensor module pointer
|
||||
* @param[in] err_cb General Error callback function
|
||||
* @param[in] err_cb_ctx General Error callback user context
|
||||
*
|
||||
* @return VCS_RESULT_OK if success
|
||||
*
|
||||
* The bmkt_open function must be called to open a specific sensor module. Returned sensor module pointer
|
||||
* must be passed to all other interface functions that expect a sensor pointer.
|
||||
*/
|
||||
|
||||
int
|
||||
bmkt_open(
|
||||
bmkt_ctx_t * ctx,
|
||||
bmkt_sensor_t ** sensor,
|
||||
bmkt_general_error_cb_t err_cb,
|
||||
void * err_cb_ctx,
|
||||
libusb_device_handle * handle);
|
||||
|
||||
/**
|
||||
* bmkt_close:
|
||||
* @brief Close the specified sensor module, and release all the resources
|
||||
*
|
||||
* @param[in] sensor The sensor module pointer
|
||||
*
|
||||
* @return VCS_RESULT_OK if success
|
||||
*
|
||||
* The bmkt_close function must be invoked when the sensor module is no longer needed.
|
||||
*/
|
||||
int
|
||||
bmkt_close(
|
||||
bmkt_sensor_t * sensor);
|
||||
|
||||
/**
|
||||
* bmkt_init_fps:
|
||||
* @brief Initialize the sensor module.
|
||||
*
|
||||
* @param[in] sensor The sensor module pointer
|
||||
*
|
||||
* @return VCS_RESULT_OK if success
|
||||
*
|
||||
* Initializes the fingerprint sensor module. Must be the first command to be issued to the fingerprint sensor module, before any other commands are issued.
|
||||
*/
|
||||
int
|
||||
bmkt_init_fps(
|
||||
bmkt_sensor_t * sensor);
|
||||
|
||||
/**
|
||||
* bmkt_enroll:
|
||||
* @brief Put the fingerprint sensor module into enrollment mode to Enroll a user’s fingerprint into the system.
|
||||
*
|
||||
* @param[in] sensor The sensor module pointer
|
||||
* @param[in] user_id Enrolled User ID
|
||||
* @param[in] user_id_len Enrolled User ID lenght
|
||||
* @param[in] finger_id Enrolled finger ID
|
||||
* @param[in] resp_cb Responce callback function. Available responses:
|
||||
* - BMKT_RSP_ENROLL_READY
|
||||
* - BMKT_RSP_CAPTURE_COMPLETE
|
||||
* - BMKT_RSP_ENROLL_REPORT
|
||||
* - BMKT_RSP_ENROLL_PAUSED
|
||||
* - BMKT_RSP_ENROLL_RESUMED
|
||||
* - BMKT_RSP_ENROLL_FAIL
|
||||
* - BMKT_RSP_ENROLL_OK
|
||||
|
||||
* @param[in] cb_ctx Responce callback user context
|
||||
*
|
||||
* @return VCS_RESULT_OK if success
|
||||
*
|
||||
* Enrolled users have to touch the fingerprint sensor multiple times based on cues provided by the system.
|
||||
* After successful enrollment, a template is generated from features of the user’s fingerprint and stored
|
||||
* in encrypted storage within the fingerprint sensor module.
|
||||
* When this command is being executed, fingerprint sensor module’s mode is: Enrollment
|
||||
*/
|
||||
int
|
||||
bmkt_enroll(
|
||||
bmkt_sensor_t * sensor,
|
||||
const uint8_t * user_id,
|
||||
uint32_t user_id_len,
|
||||
uint8_t finger_id,
|
||||
bmkt_resp_cb_t resp_cb,
|
||||
void * cb_ctx);
|
||||
|
||||
/**
|
||||
* bmkt_verify:
|
||||
* @brief Put the fingerprint sensor module into verification mode.
|
||||
*
|
||||
* @param[in] sensor The sensor module pointer
|
||||
* @param[in] user Enrolled User
|
||||
* @param[in] resp_cb Responce callback function. Available responses:
|
||||
* - BMKT_RSP_CAPTURE_COMPLETE
|
||||
* - BMKT_RSP_VERIFY_READY
|
||||
* - BMKT_RSP_VERIFY_FAIL
|
||||
* - BMKT_RSP_VERIFY_OK
|
||||
* @param[in] cb_ctx Responce callback user context
|
||||
*
|
||||
* @return VCS_RESULT_OK if success
|
||||
*
|
||||
* The user being verifyed has to touch the fingerprint sensor once based on a cue provided by the system.
|
||||
* The Captured fingerprint is matched only against the stored templates corresponding to specifyed user ID,
|
||||
* If a user’s fingerprint cannot be matched to any of the stored fingerprint templates of the specified user or
|
||||
* if the fingerprint sensor module detects that the fingerprint being presented to the sensor is a spoof,
|
||||
* then an error response is generated.
|
||||
* When this command is being executed, fingerprint sensor module’s mode is: Verification
|
||||
*/
|
||||
int
|
||||
bmkt_verify(
|
||||
bmkt_sensor_t * sensor,
|
||||
bmkt_user_id_t* user,
|
||||
bmkt_resp_cb_t resp_cb,
|
||||
void * cb_ctx);
|
||||
|
||||
|
||||
/**
|
||||
* bmkt_delete_enrolled_user:
|
||||
* @brief Delete a specific fingerprint template of an enrolled user from the database.
|
||||
*
|
||||
* @param[in] sensor The sensor module pointer
|
||||
* @param[in] finger_id Finger ID to be deleted
|
||||
* @param[in] user_id User ID to be deleted
|
||||
* @param[in] user_id_len User ID lenght
|
||||
* @param[in] resp_cb Responce callback function. Available responses:
|
||||
* - BMKT_RSP_DEL_USER_FP_FAIL
|
||||
* - BMKT_RSP_DEL_USER_FP_OK
|
||||
* @param[in] cb_ctx Responce callback user context
|
||||
*
|
||||
* @return VCS_RESULT_OK if success
|
||||
*
|
||||
* If the value of finger ID is set equal to 0 then all fingerprints of that user will be deleted from the database.
|
||||
* If the value of user ID is set to an empty string (string with length 0) and the finger ID is set equal to 0 then
|
||||
* all templates stored in the fingerprint database which are marked as corrupt will be deleted.
|
||||
* When this command is being executed, fingerprint sensor module’s mode is: Database operations
|
||||
*/
|
||||
int
|
||||
bmkt_delete_enrolled_user(
|
||||
bmkt_sensor_t * sensor,
|
||||
uint8_t finger_id,
|
||||
const char * user_id,
|
||||
uint32_t user_id_len,
|
||||
bmkt_resp_cb_t resp_cb,
|
||||
void * cb_ctx);
|
||||
|
||||
|
||||
/**
|
||||
* bmkt_register_finger_event_notification:
|
||||
* @brief Register finger presence event callback function
|
||||
*
|
||||
* @param[in] sensor The sensor module pointer
|
||||
* @param[in] cb Event callback function
|
||||
* @param[in] cb_ctx Event callback user context
|
||||
*
|
||||
* @return VCS_RESULT_OK if success
|
||||
*
|
||||
* The registered callback function will be called whenever a finger is detected as being placed on the sensor or removed from the sensor.
|
||||
*/
|
||||
int
|
||||
bmkt_register_finger_event_notification(
|
||||
bmkt_sensor_t * sensor,
|
||||
bmkt_event_cb_t cb,
|
||||
void * cb_ctx);
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BMKT_OP_STATE_START = -1,
|
||||
BMKT_OP_STATE_GET_RESP,
|
||||
BMKT_OP_STATE_WAIT_INTERRUPT,
|
||||
BMKT_OP_STATE_SEND_ASYNC,
|
||||
BMKT_OP_STATE_COMPLETE,
|
||||
} bmkt_op_state_t;
|
||||
void bmkt_op_set_state(bmkt_sensor_t* sensor, bmkt_op_state_t state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BMKT_H_ */
|
||||
@@ -1,397 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "bmkt_internal.h"
|
||||
#include "bmkt_response.h"
|
||||
#include "bmkt_message.h"
|
||||
#include "usb_transport.h"
|
||||
#include "sensor.h"
|
||||
|
||||
static int parse_error_response(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
if (msg_resp->payload_len != 2)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
resp->result = (msg_resp->payload[0] << 8) | msg_resp->payload[1];
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_init_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_init_resp_t *init_resp = &resp->response.init_resp;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
init_resp->finger_presence = extract8(msg_resp->payload, NULL);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int parse_fps_mode_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
int offset = 0;
|
||||
bmkt_fps_mode_resp_t *fps_mode_resp = &resp->response.fps_mode_resp;
|
||||
|
||||
if (msg_resp->payload_len != sizeof(bmkt_fps_mode_resp_t))
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
fps_mode_resp->mode = extract8(msg_resp->payload, &offset);
|
||||
fps_mode_resp->level2_mode = extract8(msg_resp->payload, &offset);
|
||||
fps_mode_resp->cmd_id = extract8(msg_resp->payload, &offset);
|
||||
fps_mode_resp->finger_presence = extract8(msg_resp->payload, &offset);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_enroll_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
enroll_resp->progress = extract8(msg_resp->payload, NULL);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_enroll_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
|
||||
|
||||
if (msg_resp->payload_len < 1 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 1))
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
enroll_resp->finger_id = msg_resp->payload[0];
|
||||
memcpy(enroll_resp->user_id, &msg_resp->payload[1], msg_resp->payload_len - 1);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_auth_ok(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_identify_resp_t *id_resp = &resp->response.id_resp;
|
||||
|
||||
if (msg_resp->payload_len < 3 || msg_resp->payload_len > (BMKT_MAX_USER_ID_LEN + 3))
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
id_resp->match_result = (double)msg_resp->payload[0] + 0.01 * (double)msg_resp->payload[1];
|
||||
id_resp->finger_id = msg_resp->payload[2];
|
||||
memcpy(id_resp->user_id, &msg_resp->payload[3], msg_resp->payload_len - 3);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_security_level_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_set_sec_level_resp_t *sec_level_resp = &resp->response.sec_level_resp;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
sec_level_resp->sec_level = extract8(msg_resp->payload, NULL);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_del_all_users_progress_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_del_all_users_resp_t *del_all_users_resp = &resp->response.del_all_users_resp;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
del_all_users_resp->progress = extract8(msg_resp->payload, NULL);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_db_cap_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_get_db_capacity_resp_t *db_cap_resp = &resp->response.db_cap_resp;
|
||||
int offset = 0;
|
||||
|
||||
if (msg_resp->payload_len < 2 || msg_resp->payload_len > 4)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
db_cap_resp->total = extract8(msg_resp->payload, &offset);
|
||||
db_cap_resp->empty = extract8(msg_resp->payload, &offset);
|
||||
|
||||
if (msg_resp->payload_len == 4)
|
||||
{
|
||||
db_cap_resp->bad_slots = extract8(msg_resp->payload, &offset);
|
||||
db_cap_resp->corrupt_templates = extract8(msg_resp->payload, &offset);
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_get_enrolled_fingers_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
int offset = 0;
|
||||
int i = 0;
|
||||
|
||||
if (msg_resp->payload_len < 2)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
/* 2 bytes per finger so calculate the total number of fingers to process*/
|
||||
int num_fingers = (msg_resp->payload_len) / 2;
|
||||
|
||||
bmkt_enrolled_fingers_resp_t *get_enrolled_fingers_resp = &resp->response.enrolled_fingers_resp;
|
||||
|
||||
for (i = 0; i < num_fingers; i++)
|
||||
{
|
||||
get_enrolled_fingers_resp->fingers[i].finger_id = extract8(msg_resp->payload, &offset);
|
||||
get_enrolled_fingers_resp->fingers[i].template_status = extract8(msg_resp->payload, &offset);
|
||||
|
||||
}
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
static int parse_get_enrolled_users_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
int offset = 0;
|
||||
int i = 0;
|
||||
|
||||
/* the payload is 2 bytes + template data */
|
||||
if (msg_resp->payload_len < 2)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
bmkt_enroll_templates_resp_t *get_enroll_templates_resp = &resp->response.enroll_templates_resp;
|
||||
|
||||
get_enroll_templates_resp->total_query_messages = extract8(msg_resp->payload, &offset);
|
||||
get_enroll_templates_resp->query_sequence = extract8(msg_resp->payload, &offset);
|
||||
|
||||
int n = 0;
|
||||
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
||||
{
|
||||
if (offset >= msg_resp->payload_len)
|
||||
break;
|
||||
get_enroll_templates_resp->templates[n].user_id_len = extract8(msg_resp->payload, &offset) - 2;
|
||||
if(get_enroll_templates_resp->templates[n].user_id_len > BMKT_MAX_USER_ID_LEN)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
get_enroll_templates_resp->templates[n].template_status = extract8(msg_resp->payload, &offset);
|
||||
get_enroll_templates_resp->templates[n].finger_id = extract8(msg_resp->payload, &offset);
|
||||
for (i = 0; i < get_enroll_templates_resp->templates[n].user_id_len; i++)
|
||||
{
|
||||
get_enroll_templates_resp->templates[n].user_id[i] = extract8(msg_resp->payload, &offset);
|
||||
}
|
||||
get_enroll_templates_resp->templates[n].user_id[i] = '\0';
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static int parse_get_version_report(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
bmkt_get_version_resp_t *get_version_resp = &resp->response.get_version_resp;
|
||||
int offset = 0;
|
||||
|
||||
if (msg_resp->payload_len != 15)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
memcpy(get_version_resp->part, msg_resp->payload, BMKT_PART_NUM_LEN);
|
||||
offset += BMKT_PART_NUM_LEN;
|
||||
get_version_resp->year = extract8(msg_resp->payload, &offset);
|
||||
get_version_resp->week = extract8(msg_resp->payload, &offset);
|
||||
get_version_resp->patch = extract8(msg_resp->payload, &offset);
|
||||
memcpy(get_version_resp->supplier_id, msg_resp->payload + offset, BMKT_SUPPLIER_ID_LEN);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
|
||||
uint8_t payload_size, uint8_t *payload)
|
||||
{
|
||||
int message_len = BMKT_MESSAGE_HEADER_LEN + payload_size;
|
||||
|
||||
if (*cmd_len < message_len)
|
||||
{
|
||||
return BMKT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
cmd[BMKT_MESSAGE_HEADER_ID_FIELD] = BMKT_MESSAGE_HEADER_ID;
|
||||
cmd[BMKT_MESSAGE_SEQ_NUM_FIELD] = seq_num;
|
||||
cmd[BMKT_MESSAGE_ID_FIELD] = msg_id;
|
||||
cmd[BMKT_MESSAGE_PAYLOAD_LEN_FIELD] = payload_size;
|
||||
memcpy(&cmd[BMKT_MESSAGE_PAYLOAD_FIELD], payload, payload_size);
|
||||
|
||||
*cmd_len = message_len;
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_parse_message_header(uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp)
|
||||
{
|
||||
if (resp_buf[BMKT_MESSAGE_HEADER_ID_FIELD] != BMKT_MESSAGE_HEADER_ID)
|
||||
{
|
||||
return BMKT_CORRUPT_MESSAGE;
|
||||
}
|
||||
|
||||
msg_resp->seq_num = resp_buf[BMKT_MESSAGE_SEQ_NUM_FIELD];
|
||||
msg_resp->msg_id = resp_buf[BMKT_MESSAGE_ID_FIELD];
|
||||
msg_resp->payload_len = resp_buf[BMKT_MESSAGE_PAYLOAD_LEN_FIELD];
|
||||
if (msg_resp->payload_len > 0)
|
||||
{
|
||||
msg_resp->payload = &resp_buf[BMKT_MESSAGE_PAYLOAD_FIELD];
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_resp->payload = NULL;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp)
|
||||
{
|
||||
int ret = BMKT_SUCCESS;
|
||||
|
||||
memset(resp, 0, sizeof(bmkt_response_t));
|
||||
|
||||
resp->response_id = msg_resp->msg_id;
|
||||
|
||||
switch(msg_resp->msg_id)
|
||||
{
|
||||
case BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL:
|
||||
case BMKT_RSP_SENSOR_MODULE_TEST_FAIL:
|
||||
case BMKT_RSP_FPS_INIT_FAIL:
|
||||
case BMKT_RSP_FPS_MODE_FAIL:
|
||||
case BMKT_RSP_SET_SECURITY_LEVEL_FAIL:
|
||||
case BMKT_RSP_GET_SECURITY_LEVEL_FAIL:
|
||||
case BMKT_RSP_CANCEL_OP_FAIL:
|
||||
case BMKT_RSP_ENROLL_FAIL:
|
||||
case BMKT_RSP_ID_FAIL:
|
||||
case BMKT_RSP_VERIFY_FAIL:
|
||||
case BMKT_RSP_QUERY_FAIL:
|
||||
case BMKT_RSP_DEL_USER_FP_FAIL:
|
||||
case BMKT_RSP_DEL_FULL_DB_FAIL:
|
||||
case BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
|
||||
case BMKT_RSP_POWER_DOWN_FAIL:
|
||||
case BMKT_RSP_GET_VERSION_FAIL:
|
||||
case BMKT_RSP_DISABLE_PAIRING_FAIL:
|
||||
case BMKT_RSP_QUERY_PAIRING_FAIL:
|
||||
case BMKT_RSP_SENSOR_STATUS_FAIL:
|
||||
case BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
|
||||
ret = parse_error_response(msg_resp, resp);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_FPS_INIT_OK:
|
||||
ret = parse_init_ok(msg_resp, resp);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_CANCEL_OP_OK:
|
||||
case BMKT_RSP_DEL_FULL_DB_OK:
|
||||
case BMKT_RSP_DEL_USER_FP_OK:
|
||||
/* responses with a payload of 0
|
||||
so the response indicates success */
|
||||
resp->result = BMKT_SUCCESS;
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_FPS_MODE_REPORT:
|
||||
// parse_fps_mode
|
||||
ret = parse_fps_mode_report(msg_resp, resp);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
|
||||
case BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
|
||||
/* parse security level result */
|
||||
ret = parse_security_level_report(msg_resp, resp);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_DELETE_PROGRESS:
|
||||
ret = parse_del_all_users_progress_report(msg_resp, resp);
|
||||
break;
|
||||
|
||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
||||
resp->result = BMKT_SUCCESS;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_ENROLL_READY:
|
||||
resp->result = BMKT_SUCCESS;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_ENROLL_REPORT:
|
||||
ret = parse_enroll_report(msg_resp, resp);
|
||||
break;
|
||||
|
||||
case BMKT_RSP_ENROLL_OK:
|
||||
resp->complete = 1;
|
||||
ret = parse_enroll_ok(msg_resp, resp);
|
||||
break;
|
||||
|
||||
case BMKT_RSP_ID_OK:
|
||||
case BMKT_RSP_VERIFY_OK:
|
||||
ret = parse_auth_ok(msg_resp, resp);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
case BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
||||
ret = parse_get_enrolled_fingers_report(msg_resp, resp);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
case BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
||||
resp->complete = 1;
|
||||
ret = parse_db_cap_report(msg_resp, resp);
|
||||
break;
|
||||
case BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
||||
ret = parse_get_enrolled_users_report(msg_resp, resp);
|
||||
break;
|
||||
case BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
||||
resp->complete = 1;
|
||||
break;
|
||||
|
||||
case BMKT_RSP_VERSION_INFO:
|
||||
ret = parse_get_version_report(msg_resp, resp);
|
||||
resp->complete = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BMKT_MESSAGE_H_
|
||||
#define BMKT_MESSAGE_H_
|
||||
|
||||
#include "bmkt_internal.h"
|
||||
|
||||
#define BMKT_MESSAGE_HEADER_ID 0xFE
|
||||
#define BMKT_MESSAGE_HEADER_LEN (4)
|
||||
#define BMKT_MESSAGE_CRC32_LEN (4)
|
||||
#define BMKT_MESSAGE_HEADER_ID_FIELD 0
|
||||
#define BMKT_MESSAGE_SEQ_NUM_FIELD 1
|
||||
#define BMKT_MESSAGE_ID_FIELD 2
|
||||
#define BMKT_MESSAGE_PAYLOAD_LEN_FIELD 3
|
||||
#define BMKT_MESSAGE_PAYLOAD_FIELD 4
|
||||
|
||||
// Command messages
|
||||
#define BMKT_CMD_CONTINUOUS_IMAGE_CAPTURE 0x01
|
||||
#define BMKT_CMD_CONTINUOUS_IMAGE_CAPTURE_STOP 0x04
|
||||
#define BMKT_CMD_SENSOR_MODULE_TEST 0x06
|
||||
#define BMKT_CMD_SENSOR_MODULE_TEST_START 0x08
|
||||
#define BMKT_CMD_NEXT_TEST_REPORT_CHUNK 0x0B
|
||||
#define BMKT_CMD_FPS_INIT 0x11
|
||||
#define BMKT_CMD_GET_FPS_MODE 0x21
|
||||
#define BMKT_CMD_SET_SECURITY_LEVEL 0x31
|
||||
#define BMKT_CMD_GET_SECURITY_LEVEL 0x34
|
||||
#define BMKT_CMD_CANCEL_OP 0x41
|
||||
#define BMKT_CMD_ENROLL_USER 0x51
|
||||
#define BMKT_CMD_ENROLL_PAUSE 0x52
|
||||
#define BMKT_CMD_ENROLL_RESUME 0x53
|
||||
#define BMKT_CMD_ID_USER 0x61
|
||||
#define BMKT_CMD_VERIFY_USER 0x65
|
||||
#define BMKT_CMD_GET_TEMPLATE_RECORDS 0x71
|
||||
#define BMKT_CMD_GET_NEXT_QUERY_RESPONSE 0x72
|
||||
#define BMKT_CMD_GET_ENROLLED_FINGERS 0x73
|
||||
#define BMKT_CMD_GET_DATABASE_CAPACITY 0x74
|
||||
#define BMKT_CMD_DEL_USER_FP 0x81
|
||||
#define BMKT_CMD_DEL_FULL_DB 0x84
|
||||
#define BMKT_CMD_REPEAT_LAST_RSP 0x92
|
||||
#define BMKT_CMD_POWER_DOWN_NOTIFY 0xA1
|
||||
#define BMKT_CMD_GET_VERSION 0xB1
|
||||
#define BMKT_CMD_DISABLE_PAIRING 0xC2
|
||||
#define BMKT_CMD_QUERY_PAIRING 0xC5
|
||||
#define BMKT_CMD_SENSOR_STATUS 0xD1
|
||||
#define BMKT_CMD_ID_USER_IN_ORDER 0xE1
|
||||
#define BMKT_CMD_ID_NEXT_USER 0xE3
|
||||
#define BMKT_CMD_VERIFY_USER_IN_ORDER 0xF1
|
||||
#define BMKT_CMD_VERIFY_FINGERS_IN_ORDER 0xF2
|
||||
#define BMKT_CMD_GET_FINAL_RESULT 0xE4
|
||||
|
||||
#define BMKT_EVT_FINGER_REPORT 0x91
|
||||
|
||||
#define BMKT_EVT_FINGER_STATE_NOT_ON_SENSOR 0x00
|
||||
#define BMKT_EVT_FINGER_STATE_ON_SENSOR 0x01
|
||||
|
||||
typedef struct bmkt_msg_resp
|
||||
{
|
||||
uint8_t msg_id;
|
||||
uint8_t seq_num;
|
||||
uint8_t payload_len;
|
||||
uint8_t *payload;
|
||||
int result;
|
||||
} bmkt_msg_resp_t;
|
||||
|
||||
typedef struct bmkt_session_ctx
|
||||
{
|
||||
uint8_t seq_num;
|
||||
bmkt_resp_cb_t resp_cb;
|
||||
void *cb_ctx;
|
||||
} bmkt_session_ctx_t;
|
||||
|
||||
int bmkt_compose_message(uint8_t *cmd, int *cmd_len, uint8_t msg_id, uint8_t seq_num,
|
||||
uint8_t payload_size, uint8_t *payload);
|
||||
|
||||
int bmkt_parse_message_header(uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp);
|
||||
int bmkt_parse_message_payload(bmkt_msg_resp_t *msg_resp, bmkt_response_t *resp);
|
||||
#endif /* BMKT_MESSAGE_H_ */
|
||||
@@ -1,487 +0,0 @@
|
||||
/*
|
||||
* Synaptics MiS Fingerprint Sensor Response Data Interface
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BMKT_RESPONSE_H_
|
||||
#define _BMKT_RESPONSE_H_
|
||||
|
||||
/** List of response message IDs */
|
||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_FAIL 0x02
|
||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_READY 0x03
|
||||
#define BMKT_RSP_CONTINUOUS_IMAGE_CAPTURE_STOPPED 0x05
|
||||
#define BMKT_RSP_SENSOR_MODULE_TEST_READY 0x07
|
||||
#define BMKT_RSP_SENSOR_MODULE_TEST_FAIL 0x09
|
||||
#define BMKT_RSP_SENSOR_MODULE_TEST_REPORT 0x0A
|
||||
#define BMKT_RSP_NEXT_TEST_REPORT_CHUNK 0x0C
|
||||
|
||||
/*! \addtogroup init
|
||||
* Response IDs returned by fingerprint initialization operation
|
||||
* @{
|
||||
*/
|
||||
/** Failed to initialize fingerprint sensor module */
|
||||
#define BMKT_RSP_FPS_INIT_FAIL 0x12
|
||||
/** Successfully initialized fingerprint sensor module */
|
||||
#define BMKT_RSP_FPS_INIT_OK 0x13
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup mode
|
||||
* Response IDs returned by get fingerprint mode operation
|
||||
* @{
|
||||
*/
|
||||
/** Failed to get fingerprint sensor module’s current operational mode */
|
||||
#define BMKT_RSP_FPS_MODE_FAIL 0x22
|
||||
/**
|
||||
* BMKT_RSP_FPS_MODE_REPORT:
|
||||
* Response containing the current operational mode of the fingerprint sensor module
|
||||
* <br>Payload data represented in \ref bmkt_fps_mode_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_FPS_MODE_REPORT 0x23
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup setseclevel
|
||||
* Response IDs returned by set security level operation
|
||||
* @{
|
||||
*/
|
||||
/** Failed to set fingerprint sensor module security level */
|
||||
#define BMKT_RSP_SET_SECURITY_LEVEL_FAIL 0x32
|
||||
/**
|
||||
* BMKT_RSP_SET_SECURITY_LEVEL_REPORT:
|
||||
* Security level of the fingerprint sensor module was set successfully
|
||||
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_SET_SECURITY_LEVEL_REPORT 0x33
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup getseclevel
|
||||
* Response IDs returned by get security level operation
|
||||
* @{
|
||||
*/
|
||||
/** Failed to get fingerprint sensor module security level */
|
||||
#define BMKT_RSP_GET_SECURITY_LEVEL_FAIL 0x35
|
||||
/**
|
||||
* BMKT_RSP_GET_SECURITY_LEVEL_REPORT:
|
||||
* Returns the current security level of the fingerprint sensor module
|
||||
* <br>Contains payload data represented in \ref bmkt_set_sec_level_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_GET_SECURITY_LEVEL_REPORT 0x36
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup cancelop
|
||||
* Response IDs returned by cancel_operation operation
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* BMKT_RSP_CANCEL_OP_OK:
|
||||
* Successfully canceled the current operation and returned
|
||||
* fingerprint sensor module to idle mode
|
||||
*/
|
||||
#define BMKT_RSP_CANCEL_OP_OK 0x42
|
||||
/** Failed to cancel the current operation */
|
||||
#define BMKT_RSP_CANCEL_OP_FAIL 0x43
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup enrollment
|
||||
* Response IDs returned by enrollment operation
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* BMKT_RSP_ENROLL_READY:
|
||||
* Fingerprint enrollment session has begun and the user can place
|
||||
* their finger on the sensor
|
||||
*/
|
||||
#define BMKT_RSP_ENROLL_READY 0x54
|
||||
/** Progress of the currently on-going fingerprint enrollment session */
|
||||
#define BMKT_RSP_ENROLL_REPORT 0x55
|
||||
/** Enrollment has been paused */
|
||||
#define BMKT_RSP_ENROLL_PAUSED 0x56
|
||||
/** Enrollment has been resume */
|
||||
#define BMKT_RSP_ENROLL_RESUMED 0x57
|
||||
/** The current enrollment session has encountered an error */
|
||||
#define BMKT_RSP_ENROLL_FAIL 0x58
|
||||
/**
|
||||
* BMKT_RSP_ENROLL_OK:
|
||||
* User has been successfully enrolled into the fingerprint sensor module
|
||||
* <br>Contains payload data represented in \ref bmkt_enroll_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_ENROLL_OK 0x59
|
||||
|
||||
/**
|
||||
* BMKT_RSP_CAPTURE_COMPLETE:
|
||||
* Fingerprint image capture is complete and it is safe for the user
|
||||
* to lift their finger off the sensor
|
||||
*/
|
||||
#define BMKT_RSP_CAPTURE_COMPLETE 0x60
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup identify
|
||||
* Response IDs returned by identify operation.
|
||||
* @{
|
||||
*/
|
||||
/* Fingerprint identification session has begun */
|
||||
#define BMKT_RSP_ID_READY 0x62
|
||||
/* Identification has failed */
|
||||
#define BMKT_RSP_ID_FAIL 0x63
|
||||
/**
|
||||
* BMKT_RSP_ID_OK:
|
||||
* User has been successfully identified
|
||||
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
|
||||
*/
|
||||
#define BMKT_RSP_ID_OK 0x64
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup verify
|
||||
* Response IDs returned by identify operation.
|
||||
* @{
|
||||
*/
|
||||
/** Fingerprint verification session has begun */
|
||||
#define BMKT_RSP_VERIFY_READY 0x66
|
||||
/** Verification has failed */
|
||||
#define BMKT_RSP_VERIFY_FAIL 0x67
|
||||
/**
|
||||
* BMKT_RSP_VERIFY_OK:
|
||||
* User’s identity has been successfully verified
|
||||
* <br>Contains payload data represented in \ref bmkt_auth_resp struct
|
||||
*/
|
||||
#define BMKT_RSP_VERIFY_OK 0x68
|
||||
/*! @} */
|
||||
|
||||
/**
|
||||
* BMKT_RSP_TEMPLATE_RECORDS_REPORT:
|
||||
* Response ID returned by get enrolled users templates record operation
|
||||
* <br>Returns list of template records containing user IDs and corresponding finger IDs
|
||||
* <br>Payload data represented in \ref bmkt_enroll_templates_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_TEMPLATE_RECORDS_REPORT 0x75
|
||||
|
||||
/**
|
||||
* BMKT_RSP_QUERY_RESPONSE_COMPLETE:
|
||||
* Response ID returned by get next query response operation
|
||||
* <br>Complete sequence of messages containing the template records query response has been sent
|
||||
*/
|
||||
#define BMKT_RSP_QUERY_RESPONSE_COMPLETE 0x76
|
||||
|
||||
/**
|
||||
* BMKT_RSP_GET_ENROLLED_FINGERS_REPORT:
|
||||
* Response ID returned by get enrolled fingers operation
|
||||
* <br> Returns list of IDs of enrolled fingers for a specific user,
|
||||
* along with template record status corresponding to each enrolled finger
|
||||
* <br>Contains payload data represented in \ref bmkt_enrolled_fingers_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_GET_ENROLLED_FINGERS_REPORT 0x77
|
||||
|
||||
/*! \addtogroup dbcapacity
|
||||
* Response IDs returned by get database capacity operation
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* BMKT_RSP_DATABASE_CAPACITY_REPORT:
|
||||
* Response specifying total capacity of fingerprint template database and
|
||||
* how much free capacity is remaining along with how many templates are corrupted and
|
||||
* how many bad (permanently unusable) storage slots are there.
|
||||
* <br>Payload data represented in \ref bmkt_get_db_capacity_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_DATABASE_CAPACITY_REPORT 0x78
|
||||
/** Failed to execute database query */
|
||||
#define BMKT_RSP_QUERY_FAIL 0x79
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup deluser
|
||||
* Response IDs returned by delete fingerprint of specific user operation
|
||||
* @{
|
||||
*/
|
||||
/** Failed to delete a user’s fingerprint template from the database */
|
||||
#define BMKT_RSP_DEL_USER_FP_FAIL 0x82
|
||||
/**
|
||||
* BMKT_RSP_DEL_USER_FP_OK:
|
||||
* Fingerprint template successfully deleted from the database.
|
||||
* Returns the user ID and finger ID deleted. If value of finger ID is set equal to 0,
|
||||
* then all fingerprint templates for that user have been deleted from the database
|
||||
* <br>Payload data represented in \ref bmkt_del_user_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_DEL_USER_FP_OK 0x83
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup delfulldb
|
||||
* Response IDs returned by delete entire fingerprint template DB operation
|
||||
* @{
|
||||
*/
|
||||
/** Failed to erase entire fingerprint template database */
|
||||
#define BMKT_RSP_DEL_FULL_DB_FAIL 0x85
|
||||
/** Successfully erased entire fingerprint template database */
|
||||
#define BMKT_RSP_DEL_FULL_DB_OK 0x86
|
||||
/**
|
||||
* BMKT_RSP_DELETE_PROGRESS:
|
||||
* Notify progress made during the on-going deletion of the full template database
|
||||
* <br>Payload data represented in \ref bmkt_del_all_users_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_DELETE_PROGRESS 0x87
|
||||
/*! @} */
|
||||
|
||||
/**
|
||||
* BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL:
|
||||
* Response ID returned by repeate last response operation
|
||||
* <br>Failed to retrieve and re-send last response
|
||||
*/
|
||||
#define BMKT_RSP_REPEAT_LAST_BMKT_RSP_FAIL 0x93
|
||||
|
||||
/*! \addtogroup pwrdwn
|
||||
* Response IDs returned by power down notify operation
|
||||
* @{
|
||||
*/
|
||||
/** Fingerprint sensor module is ready to be powered down */
|
||||
#define BMKT_RSP_POWER_DOWN_READY 0xA2
|
||||
/** Failed to go into power down mode */
|
||||
#define BMKT_RSP_POWER_DOWN_FAIL 0xA3
|
||||
/*! @} */
|
||||
|
||||
/*! \addtogroup versioninfo
|
||||
* Response IDs returned by get version operation
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* BMKT_RSP_VERSION_INFO:
|
||||
* System version information of the fingerprint sensor module
|
||||
* <br>Payload data represented in \ref bmkt_get_version_resp_t struct
|
||||
*/
|
||||
#define BMKT_RSP_VERSION_INFO 0xB2
|
||||
/* Failed to retrieve and send last response */
|
||||
#define BMKT_RSP_GET_VERSION_FAIL 0xB3
|
||||
/*! @} */
|
||||
|
||||
/**
|
||||
* BMKT_RSP_GENERAL_ERROR:
|
||||
* Not tied to a specific command-response session.
|
||||
* <br>Could be caused by corrupt or truncated command message
|
||||
*/
|
||||
#define BMKT_RSP_GENERAL_ERROR 0xC1
|
||||
#define BMKT_RSP_DISABLE_PAIRING_FAIL 0xC3
|
||||
#define BMKT_RSP_DISABLE_PAIRING_OK 0xC4
|
||||
#define BMKT_RSP_QUERY_PAIRING_FAIL 0xC6
|
||||
#define BMKT_RSP_SENSOR_PAIRING_REPORT 0xC7
|
||||
|
||||
/*! \addtogroup versioninfo
|
||||
* Response IDs returned by get sensor module status operation
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* BMKT_RSP_SENSOR_STATUS_REPORT:
|
||||
* Response returning the current status of the sensor module
|
||||
* <br>Payload data represented in bmkt_XXX struct
|
||||
*/
|
||||
#define BMKT_RSP_SENSOR_STATUS_REPORT 0xD2
|
||||
/** Failed to retrieve sensor status */
|
||||
#define BMKT_RSP_SENSOR_STATUS_FAIL 0xD3
|
||||
/*! @} */
|
||||
|
||||
/**
|
||||
* BMKT_RSP_SEND_NEXT_USER_ID:
|
||||
* Response ID returned by identify user in order operation
|
||||
* <br>Notify to send the next batch of user IDs in the priority list
|
||||
*/
|
||||
#define BMKT_RSP_SEND_NEXT_USER_ID 0xE2
|
||||
/**
|
||||
* BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL:
|
||||
* Response IDs returned by retrieve final result operation
|
||||
* <br>Failed to retrieve and re-send cached final result
|
||||
*/
|
||||
#define BMKT_RSP_RETRIEVE_FINAL_RESULT_FAIL 0xE5
|
||||
|
||||
/**
|
||||
* Response payload data structure returned by sensor initialization operation.
|
||||
*/
|
||||
typedef struct bmkt_init_resp
|
||||
{
|
||||
uint8_t finger_presence; /**< Indicates finger existence on the sensor during startup */
|
||||
} bmkt_init_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_enroll_resp:
|
||||
* Response payload data structure returned by enrollment operation.
|
||||
*/
|
||||
typedef struct bmkt_enroll_resp
|
||||
{
|
||||
int progress; /**< Shows current progress stutus [0-100] */
|
||||
uint8_t finger_id; /**< User's finger id [1-10] */
|
||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */
|
||||
} bmkt_enroll_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_auth_resp:
|
||||
* Response payload data structure returned by identify and verify operations.
|
||||
*/
|
||||
struct bmkt_auth_resp
|
||||
{
|
||||
double match_result; /**< match result returned by matcher */
|
||||
uint8_t finger_id; /**< Matched templates's finger id */
|
||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< Matched template's user id */
|
||||
};
|
||||
|
||||
typedef struct bmkt_auth_resp bmkt_verify_resp_t; /**< Returned by verify */
|
||||
typedef struct bmkt_auth_resp bmkt_identify_resp_t; /**< Returned by identify */
|
||||
|
||||
/**
|
||||
* bmkt_fps_mode_resp:
|
||||
* Response payload data structure returned by get fingerprint mode operation.
|
||||
*/
|
||||
typedef struct bmkt_fps_mode_resp
|
||||
{
|
||||
uint8_t mode; /**< One of the Level I bmkt_mode_t values */
|
||||
uint8_t level2_mode; /**< One of the Level II bmkt_mode_level2_t values */
|
||||
uint8_t cmd_id; /**< Message ID of command being executed when bmkt_get_fps_mode was called */
|
||||
uint8_t finger_presence; /**< Finger presence status value finger on sensor 1 / finger not on sensor 0 */
|
||||
} bmkt_fps_mode_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_get_version_resp:
|
||||
* Response payload data structure returned by get version operation.
|
||||
*/
|
||||
typedef struct bmkt_get_version_resp
|
||||
{
|
||||
uint8_t part[BMKT_PART_NUM_LEN]; /**< Software Part Number */
|
||||
uint8_t year; /**< Software Version Year */
|
||||
uint8_t week; /**< Software Version Week */
|
||||
uint8_t patch; /**< Software Version Patch Level */
|
||||
uint8_t supplier_id[BMKT_SUPPLIER_ID_LEN]; /**< Software Supplier Identification */
|
||||
} bmkt_get_version_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_get_db_capacity_resp:
|
||||
* Response payload data structure returned by get DB capacity operation.
|
||||
*/
|
||||
typedef struct bmkt_get_db_capacity_resp
|
||||
{
|
||||
uint8_t total; /**< Total Available Capacity: Total number of template records that can be stored */
|
||||
uint8_t empty; /**< Free Capacity: Number of template records that can still be stored */
|
||||
uint8_t bad_slots; /**< Number of bad template storage slots */
|
||||
uint8_t corrupt_templates; /**< Number of corrupt templates */
|
||||
} bmkt_get_db_capacity_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_sec_level:
|
||||
* Security level values.
|
||||
*/
|
||||
typedef enum bmkt_sec_level
|
||||
{
|
||||
BMKT_SECURITY_LEVEL_LOW = 0x10,
|
||||
BMKT_SECURITY_LEVEL_MEDIUM = 0x40,
|
||||
BMKT_SECURITY_LEVEL_HIGH = 0x60,
|
||||
} bmkt_sec_level_t;
|
||||
|
||||
/**
|
||||
* bmkt_set_sec_level_resp:
|
||||
* Response payload data structure returned by get/set security level operations.
|
||||
*/
|
||||
typedef struct bmkt_set_sec_level_resp
|
||||
{
|
||||
bmkt_sec_level_t sec_level; /**< One of the bmkt_sec_level_t values */
|
||||
} bmkt_set_sec_level_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_del_all_users_resp:
|
||||
* Response payload data structure returned by delete all enrolled users operation.
|
||||
*/
|
||||
typedef struct bmkt_del_all_users_resp
|
||||
{
|
||||
int progress; /**< Progress indicator as a percentage */
|
||||
} bmkt_del_all_users_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_del_user_resp:
|
||||
* Response payload data structure returned by delete enrolled user operation.
|
||||
*/
|
||||
typedef struct bmkt_del_user_resp
|
||||
{
|
||||
int progress; /**< Progress indicator as a percentage */
|
||||
} bmkt_del_user_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_enroll_template:
|
||||
* Structure of enrolled users template record data.
|
||||
*/
|
||||
typedef struct bmkt_enroll_template
|
||||
{
|
||||
uint8_t user_id_len; /**< Length of user_id string */
|
||||
uint8_t template_status; /**< Template record status */
|
||||
uint8_t finger_id; /**< ID of enrolled finger */
|
||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN + 1]; /**< Name of the enrolled user */
|
||||
} bmkt_enroll_template_t;
|
||||
|
||||
/**
|
||||
* bmkt_enroll_templates_resp:
|
||||
* Response payload data structure returned by get enrolled user list operation.
|
||||
*/
|
||||
typedef struct bmkt_enroll_templates_resp
|
||||
{
|
||||
uint8_t total_query_messages; /**< Total query response messages */
|
||||
uint8_t query_sequence; /**< Query response sequence number */
|
||||
bmkt_enroll_template_t templates[BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH]; /**< Enrolled user template records list */
|
||||
} bmkt_enroll_templates_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_enrolled_fingers:
|
||||
* Structure of template record status corresponding to each enrolled finger.
|
||||
*/
|
||||
typedef struct bmkt_enrolled_fingers
|
||||
{
|
||||
uint8_t finger_id; /**< ID of enrolled finger */
|
||||
uint8_t template_status; /**< Template record status of finger_id */
|
||||
} bmkt_enrolled_fingers_t;
|
||||
|
||||
/**
|
||||
* bmkt_enrolled_fingers_resp:
|
||||
* Response payload data structure returned by get enrolled fingers operation.
|
||||
*/
|
||||
typedef struct bmkt_enrolled_fingers_resp
|
||||
{
|
||||
bmkt_enrolled_fingers_t fingers[10]; /**< List of enroled fingers, max number of supported fingers per user is 10 */
|
||||
} bmkt_enrolled_fingers_resp_t;
|
||||
|
||||
/**
|
||||
* bmkt_response_data_t:
|
||||
* Union combining all response payload data types.
|
||||
*/
|
||||
typedef union {
|
||||
bmkt_init_resp_t init_resp;
|
||||
bmkt_enroll_resp_t enroll_resp;
|
||||
bmkt_verify_resp_t verify_resp;
|
||||
bmkt_identify_resp_t id_resp;
|
||||
bmkt_fps_mode_resp_t fps_mode_resp;
|
||||
bmkt_get_version_resp_t get_version_resp;
|
||||
bmkt_get_db_capacity_resp_t db_cap_resp;
|
||||
bmkt_set_sec_level_resp_t sec_level_resp;
|
||||
bmkt_del_all_users_resp_t del_all_users_resp;
|
||||
bmkt_enroll_templates_resp_t enroll_templates_resp;
|
||||
bmkt_del_user_resp_t del_user_resp;
|
||||
bmkt_enrolled_fingers_resp_t enrolled_fingers_resp;
|
||||
} bmkt_response_data_t;
|
||||
|
||||
/**
|
||||
* bmkt_response:
|
||||
* Structure to abstract different response structure types in one API
|
||||
* to be used in bmkt_resp_cb_t callback function.
|
||||
*/
|
||||
typedef struct bmkt_response
|
||||
{
|
||||
int response_id; /**< Response message ID, one of th BMKT_RSP_XXX */
|
||||
int result; /**< Operation execution result code */
|
||||
int complete; /**< Operation completion status 1: complete / 0: not completed */
|
||||
bmkt_response_data_t response; /**< Operation specific response union */
|
||||
} bmkt_response_t;
|
||||
|
||||
#endif /* _BMKT_RESPONSE_H_ */
|
||||
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "bmkt_internal.h"
|
||||
#include "bmkt_message.h"
|
||||
#include "sensor.h"
|
||||
|
||||
#define SENSOR_CMD_GET_VERSION 1
|
||||
#define SENSOR_CMD_ACE_COMMAND 167
|
||||
#define SENSOR_CMD_ASYNCMSG_READ 168
|
||||
|
||||
#define SENSOR_FW_CMD_HEADER_LEN 1
|
||||
#define SENSOR_FW_REPLY_HEADER_LEN 2
|
||||
|
||||
static int get_version(bmkt_sensor_t *sensor, bmkt_sensor_version_t *mis_version)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *resp = NULL;
|
||||
int resp_len = 40;
|
||||
uint16_t status = 0;
|
||||
uint8_t *cmd;
|
||||
int cmd_len = 0;
|
||||
int cmd_buf_len;
|
||||
int offset = 0;
|
||||
|
||||
ret = usb_get_command_buffer(&sensor->usb_xport, &cmd, &cmd_buf_len);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return BMKT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (cmd_buf_len < SENSOR_FW_CMD_HEADER_LEN)
|
||||
{
|
||||
return BMKT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
cmd[0] = SENSOR_CMD_GET_VERSION;
|
||||
cmd_len = 1;
|
||||
ret = usb_send_command_sync(&sensor->usb_xport, cmd_len, &resp, &resp_len);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
status = extract16(resp, &offset);
|
||||
if (status)
|
||||
{
|
||||
bmkt_err_log("The sensor reported an error when sending get version command: 0x%x",
|
||||
status);
|
||||
return BMKT_SENSOR_MALFUNCTION;
|
||||
}
|
||||
|
||||
if (resp_len < 38)
|
||||
{
|
||||
return BMKT_SENSOR_MALFUNCTION;
|
||||
}
|
||||
|
||||
mis_version->build_time = extract32(resp, &offset);
|
||||
mis_version->build_num = extract32(resp, &offset);
|
||||
mis_version->version_major = extract8(resp, &offset);
|
||||
mis_version->version_minor = extract8(resp, &offset);
|
||||
mis_version->target = extract8(resp, &offset);
|
||||
mis_version->product = extract8(resp, &offset);
|
||||
|
||||
ret = usb_release_command_buffer(&sensor->usb_xport);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("%s: failed to release command buffer: %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
static bmkt_session_ctx_t *get_empty_session_ctx(bmkt_sensor_t *sensor)
|
||||
{
|
||||
bmkt_session_ctx_t *ctx;
|
||||
int i;
|
||||
int idx;
|
||||
|
||||
for (i = 0; i < BMKT_MAX_PENDING_SESSIONS; i++)
|
||||
{
|
||||
idx = (sensor->empty_session_idx + i) % BMKT_MAX_PENDING_SESSIONS;
|
||||
ctx = &sensor->pending_sessions[idx];
|
||||
if (ctx->seq_num == 0)
|
||||
{
|
||||
sensor->empty_session_idx = (idx + 1) % BMKT_MAX_PENDING_SESSIONS;
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bmkt_session_ctx_t *get_session_ctx(bmkt_sensor_t *sensor, int seq_num)
|
||||
{
|
||||
int i;
|
||||
bmkt_session_ctx_t *ctx;
|
||||
|
||||
/* Sequence number of 0 is not valid for a response to
|
||||
a command.*/
|
||||
if (seq_num == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < BMKT_MAX_PENDING_SESSIONS; i++)
|
||||
{
|
||||
ctx = &sensor->pending_sessions[i];
|
||||
if (ctx->seq_num == seq_num)
|
||||
{
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int release_session_ctx(bmkt_sensor_t *sensor, bmkt_session_ctx_t *ctx)
|
||||
{
|
||||
|
||||
memset(ctx, 0, sizeof(bmkt_session_ctx_t));
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_sensor_open(bmkt_sensor_t *sensor, bmkt_general_error_cb_t err_cb, void *err_cb_ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sensor->seq_num = 1;
|
||||
|
||||
sensor->sensor_state = BMKT_SENSOR_STATE_UNINIT;
|
||||
sensor->usb_xport.sensor = sensor;
|
||||
ret = usb_open(&sensor->usb_xport);
|
||||
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_err_log("Failed to open transport: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sensor->gen_err_cb = err_cb;
|
||||
sensor->gen_err_cb_ctx = err_cb_ctx;
|
||||
|
||||
ret = get_version(sensor, &sensor->version);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_err_log("Failed to get version info: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bmkt_dbg_log("Build Time: %d", sensor->version.build_time);
|
||||
bmkt_dbg_log("Build Num: %d", sensor->version.build_num);
|
||||
bmkt_dbg_log("Version: %d.%d", sensor->version.version_major, sensor->version.version_minor);
|
||||
bmkt_dbg_log("Target: %d", sensor->version.target);
|
||||
bmkt_dbg_log("Product: %d", sensor->version.product);
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_sensor_close(bmkt_sensor_t *sensor)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sensor->sensor_state = BMKT_SENSOR_STATE_EXIT;
|
||||
|
||||
ret = usb_close(&sensor->usb_xport);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
sensor->sensor_state = BMKT_SENSOR_STATE_EXIT;
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_sensor_init_fps(bmkt_sensor_t *sensor)
|
||||
{
|
||||
sensor->sensor_state = BMKT_SENSOR_STATE_INIT;
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_sensor_send_message(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
||||
uint8_t *payload, bmkt_resp_cb_t resp_cb, void *cb_ctx)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *cmd;
|
||||
int cmd_buf_len = 0;
|
||||
int msg_len;
|
||||
int seq_num = 0;
|
||||
bmkt_session_ctx_t *session_ctx = get_empty_session_ctx(sensor);
|
||||
|
||||
if (session_ctx == NULL)
|
||||
{
|
||||
return BMKT_OPERATION_DENIED;
|
||||
}
|
||||
|
||||
if (sensor->seq_num > 255) {
|
||||
/* seq. number is in range [1 – 255]. After it reaches 255, it rolls over to 1 and starts over again.
|
||||
(0 is reserved for special purposes) */
|
||||
sensor->seq_num = 1;
|
||||
}
|
||||
session_ctx->seq_num = sensor->seq_num++;
|
||||
session_ctx->resp_cb = resp_cb;
|
||||
session_ctx->cb_ctx = cb_ctx;
|
||||
|
||||
bmkt_dbg_log("session_ctx->seq_num=%d, sensor->seq_num=%d", session_ctx->seq_num, sensor->seq_num);
|
||||
|
||||
bmkt_op_set_state(sensor, BMKT_OP_STATE_START);
|
||||
|
||||
ret = usb_get_command_buffer(&sensor->usb_xport, &cmd, &cmd_buf_len);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return BMKT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* MIS sensors send ACE commands encapsulated in FW commands*/
|
||||
cmd[0] = SENSOR_CMD_ACE_COMMAND;
|
||||
msg_len = cmd_buf_len - SENSOR_FW_CMD_HEADER_LEN;
|
||||
|
||||
if (session_ctx != NULL)
|
||||
{
|
||||
seq_num = session_ctx->seq_num;
|
||||
}
|
||||
|
||||
ret = bmkt_compose_message(&cmd[1], &msg_len, msg_id, seq_num, payload_size, payload);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("Failed to compose ace message: %d", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = usb_send_command(&sensor->usb_xport, msg_len + SENSOR_FW_CMD_HEADER_LEN);
|
||||
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("%s: failed to send ACE command: %d", __func__, ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
usb_release_command_buffer(&sensor->usb_xport);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
release_session_ctx(sensor, session_ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bmkt_sensor_send_async_read_command(bmkt_sensor_t *sensor)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *cmd;
|
||||
int cmd_buf_len = 0;
|
||||
|
||||
ret = usb_get_command_buffer(&sensor->usb_xport, &cmd, &cmd_buf_len);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return BMKT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* MIS sensors send ACE commands encapsulated in FW commands */
|
||||
cmd[0] = SENSOR_CMD_ASYNCMSG_READ;
|
||||
|
||||
ret = usb_send_command(&sensor->usb_xport, SENSOR_FW_CMD_HEADER_LEN);
|
||||
if (ret == BMKT_SENSOR_RESPONSE_PENDING)
|
||||
{
|
||||
/* The caller needs to handle the response before we can send this command */
|
||||
goto cleanup;
|
||||
}
|
||||
else if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
if (ret != BMKT_SENSOR_NOT_READY)
|
||||
{
|
||||
bmkt_dbg_log("%s: failed to send ACE ASYNC READ command: %d", __func__, ret);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
usb_release_command_buffer(&sensor->usb_xport);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bmkt_sensor_send_message_sync(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
||||
uint8_t *payload, uint8_t **resp_buf, int *resp_len, bmkt_response_t *resp)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *cmd;
|
||||
int cmd_buf_len = 0;
|
||||
int msg_len;
|
||||
bmkt_msg_resp_t msg_resp;
|
||||
|
||||
*resp_len = BMKT_MAX_TRANSFER_LEN;
|
||||
|
||||
ret = usb_get_command_buffer(&sensor->usb_xport, &cmd, &cmd_buf_len);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return BMKT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
cmd[0] = SENSOR_CMD_ACE_COMMAND;
|
||||
msg_len = cmd_buf_len - SENSOR_FW_CMD_HEADER_LEN;
|
||||
|
||||
ret = bmkt_compose_message(&cmd[1], &msg_len, msg_id, sensor->seq_num++, payload_size,
|
||||
payload);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("Failed to compose ace message: %d", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = usb_send_command_sync(&sensor->usb_xport, msg_len + SENSOR_FW_CMD_HEADER_LEN,
|
||||
resp_buf, resp_len);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("%s: failed to send ACE command: %d", __func__, ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = bmkt_parse_message_header(&(*resp_buf)[2], *resp_len - 2, &msg_resp);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = bmkt_parse_message_payload(&msg_resp, resp);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
ret = usb_release_command_buffer(&sensor->usb_xport);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("%s: failed to release command buffer: %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bmkt_sensor_handle_response(bmkt_sensor_t *sensor, uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp)
|
||||
{
|
||||
int ret;
|
||||
bmkt_session_ctx_t *session_ctx;
|
||||
bmkt_response_t resp;
|
||||
int i;
|
||||
|
||||
ret = bmkt_parse_message_header(&resp_buf[2], resp_len - 2, msg_resp);
|
||||
if (ret == BMKT_CORRUPT_MESSAGE)
|
||||
{
|
||||
bmkt_warn_log("Corrupt Message Received");
|
||||
return ret;
|
||||
}
|
||||
else if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (msg_resp->msg_id == BMKT_EVT_FINGER_REPORT)
|
||||
{
|
||||
/* finger event message */
|
||||
bmkt_info_log("Finger event!");
|
||||
bmkt_finger_event_t finger_event;
|
||||
|
||||
if (msg_resp->payload_len != 1)
|
||||
{
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
if (msg_resp->payload[0] == 0x01)
|
||||
{
|
||||
finger_event.finger_state = BMKT_FINGER_STATE_ON_SENSOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
finger_event.finger_state = BMKT_FINGER_STATE_NOT_ON_SENSOR;
|
||||
}
|
||||
|
||||
if (sensor->finger_event_cb != NULL)
|
||||
{
|
||||
sensor->finger_event_cb(&finger_event, sensor->finger_cb_ctx);
|
||||
}
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
if (msg_resp->seq_num == 0)
|
||||
{
|
||||
|
||||
if (msg_resp->msg_id == BMKT_RSP_GENERAL_ERROR)
|
||||
{
|
||||
/* report general error */
|
||||
bmkt_info_log("General Error!");
|
||||
uint16_t err;
|
||||
|
||||
if (sensor->gen_err_cb != NULL)
|
||||
{
|
||||
err = (msg_resp->payload[0] << 8) | msg_resp->payload[1];
|
||||
sensor->gen_err_cb(err, sensor->gen_err_cb_ctx);
|
||||
}
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
ret = bmkt_parse_message_payload(msg_resp, &resp);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_warn_log("Failed to process response: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
session_ctx = get_session_ctx(sensor, msg_resp->seq_num);
|
||||
if (session_ctx == NULL)
|
||||
{
|
||||
bmkt_warn_log("Response received with invalid sequence number: %d, return BMKT_UNRECOGNIZED_MESSAGE(112)", msg_resp->seq_num);
|
||||
return BMKT_UNRECOGNIZED_MESSAGE;
|
||||
}
|
||||
|
||||
if (session_ctx->resp_cb != NULL)
|
||||
{
|
||||
ret = session_ctx->resp_cb(&resp, session_ctx->cb_ctx);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_warn_log("response callback failed: %d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (resp.complete == 1)
|
||||
{
|
||||
ret = release_session_ctx(sensor, session_ctx);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (resp.response_id == BMKT_RSP_CANCEL_OP_OK && resp.result == BMKT_SUCCESS)
|
||||
{
|
||||
/* The previous commands have been canceled. Release all session ctx */
|
||||
for (i = 0; i < BMKT_MAX_PENDING_SESSIONS; i++)
|
||||
{
|
||||
release_session_ctx(sensor, &sensor->pending_sessions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int bmkt_register_finger_event_notification(bmkt_sensor_t *sensor, bmkt_event_cb_t cb, void *cb_ctx)
|
||||
{
|
||||
if (sensor == NULL || cb == NULL)
|
||||
{
|
||||
return BMKT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
sensor->finger_event_cb = cb;
|
||||
sensor->finger_cb_ctx = cb_ctx;
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _SENSOR_H_
|
||||
#define _SENSOR_H_
|
||||
|
||||
#include "usb_transport.h"
|
||||
#define BMKT_MAX_PENDING_SESSIONS 2
|
||||
|
||||
typedef enum bmkt_sensor_state
|
||||
{
|
||||
BMKT_SENSOR_STATE_UNINIT = 0,
|
||||
BMKT_SENSOR_STATE_IDLE,
|
||||
BMKT_SENSOR_STATE_INIT,
|
||||
BMKT_SENSOR_STATE_EXIT,
|
||||
} bmkt_sensor_state_t;
|
||||
|
||||
typedef struct bmkt_sensor_drv bmkt_sensor_drv_t;
|
||||
|
||||
typedef struct bmkt_sensor_version
|
||||
{
|
||||
uint32_t build_time;
|
||||
uint32_t build_num;
|
||||
uint8_t version_major;
|
||||
uint8_t version_minor;
|
||||
uint8_t target;
|
||||
uint8_t product;
|
||||
uint8_t silicon_rev;
|
||||
uint8_t formal_release;
|
||||
uint8_t platform;
|
||||
uint8_t patch;
|
||||
uint8_t serial_number[6];
|
||||
uint16_t security;
|
||||
uint8_t iface;
|
||||
uint8_t device_type;
|
||||
} bmkt_sensor_version_t;
|
||||
|
||||
typedef struct bmkt_sensor
|
||||
{
|
||||
bmkt_usb_transport_t usb_xport;
|
||||
bmkt_sensor_version_t version;
|
||||
bmkt_session_ctx_t pending_sessions[BMKT_MAX_PENDING_SESSIONS];
|
||||
int empty_session_idx;
|
||||
int flags;
|
||||
int seq_num;
|
||||
bmkt_sensor_state_t sensor_state;
|
||||
bmkt_event_cb_t finger_event_cb;
|
||||
void *finger_cb_ctx;
|
||||
bmkt_general_error_cb_t gen_err_cb;
|
||||
void *gen_err_cb_ctx;
|
||||
bmkt_op_state_t op_state;
|
||||
} bmkt_sensor_t;
|
||||
|
||||
int bmkt_sensor_open(bmkt_sensor_t *sensor,
|
||||
bmkt_general_error_cb_t err_cb, void *err_cb_ctx);
|
||||
int bmkt_sensor_close(bmkt_sensor_t *sensor);
|
||||
|
||||
int bmkt_sensor_init_fps(bmkt_sensor_t *sensor);
|
||||
|
||||
int bmkt_sensor_send_message(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
||||
uint8_t *payload, bmkt_resp_cb_t resp_cb, void *resp_data);
|
||||
int bmkt_sensor_send_message_sync(bmkt_sensor_t *sensor, uint8_t msg_id, uint8_t payload_size,
|
||||
uint8_t *payload, uint8_t **resp_buf, int *resp_len, bmkt_response_t *resp);
|
||||
int bmkt_sensor_handle_response(bmkt_sensor_t *sensor, uint8_t *resp_buf, int resp_len, bmkt_msg_resp_t *msg_resp);
|
||||
|
||||
int bmkt_sensor_send_async_read_command(bmkt_sensor_t *sensor);
|
||||
#endif /* _SENSOR_H_ */
|
||||
@@ -1,488 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "synaptics"
|
||||
|
||||
#include "drivers_api.h"
|
||||
#include "fpi-async.h"
|
||||
#include "fp_internal.h"
|
||||
|
||||
#include "synaptics.h"
|
||||
|
||||
|
||||
static const struct usb_id id_table[] = {
|
||||
{ .vendor = SYNAPTICS_VENDOR_ID, .product = SYNAPTICS_PRODUCT_ID_A9, },
|
||||
|
||||
{ 0, 0, 0, }, /* terminating entry */
|
||||
};
|
||||
|
||||
|
||||
static int general_error_callback(uint16_t error, void *ctx)
|
||||
{
|
||||
fp_err("Received General Error %d from the sensor", error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finger_event_callback(bmkt_finger_event_t *event, void *ctx)
|
||||
{
|
||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
|
||||
switch (event->finger_state)
|
||||
{
|
||||
case BMKT_FINGER_STATE_UNKNOWN:
|
||||
fp_info("Finger state is not known");
|
||||
break;
|
||||
case BMKT_FINGER_STATE_ON_SENSOR:
|
||||
sdev->isFingerOnSensor = TRUE;
|
||||
fp_info("Finger in on the sensor");
|
||||
break;
|
||||
case BMKT_FINGER_STATE_NOT_ON_SENSOR:
|
||||
sdev->isFingerOnSensor = FALSE;
|
||||
fp_info("Finger is not on the sensor");
|
||||
if(sdev->state == SYNA_STATE_VERIFY_DELAY_RESULT)
|
||||
{
|
||||
fp_info("verify no match");
|
||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
||||
fpi_drvcb_report_verify_result(dev, FP_VERIFY_NO_MATCH, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
struct syna_mis_print_data
|
||||
{
|
||||
uint8_t finger_id;
|
||||
uint8_t user_id[BMKT_MAX_USER_ID_LEN];
|
||||
};
|
||||
|
||||
static int enroll_response(bmkt_response_t *resp, void *ctx)
|
||||
{
|
||||
bmkt_enroll_resp_t *enroll_resp = &resp->response.enroll_resp;
|
||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
|
||||
switch (resp->response_id)
|
||||
{
|
||||
case BMKT_RSP_ENROLL_READY:
|
||||
{
|
||||
fpi_drvcb_enroll_started(dev, 0);
|
||||
sdev->enroll_resp_data.progress = 0;
|
||||
fp_info("Place Finger on the Sensor!");
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
||||
{
|
||||
fp_info("Fingerprint image capture complete!");
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_ENROLL_REPORT:
|
||||
{
|
||||
fp_info("Enrollment is %d %% ", enroll_resp->progress);
|
||||
if(enroll_resp->progress < 100)
|
||||
{
|
||||
if(sdev->enroll_resp_data.progress == enroll_resp->progress)
|
||||
fpi_drvcb_enroll_stage_completed(dev, FP_ENROLL_RETRY, NULL, NULL);
|
||||
else
|
||||
fpi_drvcb_enroll_stage_completed(dev, FP_ENROLL_PASS, NULL, NULL);
|
||||
}
|
||||
sdev->enroll_resp_data.progress = enroll_resp->progress;
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_ENROLL_PAUSED:
|
||||
{
|
||||
fp_info("Enrollment has been paused!");
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_ENROLL_RESUMED:
|
||||
{
|
||||
fp_info("Enrollment has been resumed!");
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_ENROLL_FAIL:
|
||||
{
|
||||
fp_info("Enrollment has failed!: %d", resp->result);
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_ENROLL_OK:
|
||||
{
|
||||
struct syna_mis_print_data mis_data;
|
||||
struct fp_print_data *fdata = NULL;
|
||||
struct fp_print_data_item *item = NULL;
|
||||
fdata = fpi_print_data_new(dev);
|
||||
item = fpi_print_data_item_new(sizeof(mis_data));
|
||||
fp_info("Enrollment was successful!");
|
||||
mis_data.finger_id = enroll_resp->finger_id;
|
||||
memcpy(mis_data.user_id, enroll_resp->user_id,
|
||||
BMKT_MAX_USER_ID_LEN);
|
||||
memcpy(item->data, &mis_data,
|
||||
sizeof(struct syna_mis_print_data));
|
||||
fdata->prints = g_slist_prepend(fdata->prints, item);
|
||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
||||
fpi_drvcb_enroll_stage_completed(dev, 1, fdata, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dev_init(struct fp_dev *dev, unsigned long driver_data)
|
||||
{
|
||||
synaptics_dev *sdev = NULL;
|
||||
int result = 0, ret = 0;
|
||||
|
||||
fp_info("%s ", __func__);
|
||||
|
||||
/* Set enroll stage number */
|
||||
fpi_dev_set_nr_enroll_stages(dev, ENROLL_SAMPLES);
|
||||
|
||||
/* Initialize private structure */
|
||||
sdev = g_malloc0(sizeof(synaptics_dev));
|
||||
|
||||
result = bmkt_init(&(sdev->ctx));
|
||||
if (result != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to initialize bmkt context: %d", result);
|
||||
return -1;
|
||||
}
|
||||
fp_info("bmkt_init successfully.");
|
||||
|
||||
result = bmkt_open(sdev->ctx, &sdev->sensor, general_error_callback, NULL, fpi_dev_get_usb_dev(dev));
|
||||
if (result != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to open bmkt sensor: %d", result);
|
||||
goto bmkt_cleanup;
|
||||
}
|
||||
|
||||
result = bmkt_register_finger_event_notification(sdev->sensor, finger_event_callback, dev);
|
||||
if (result != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to register finger event notification: %d", result);
|
||||
goto bmkt_cleanup;
|
||||
}
|
||||
result = bmkt_init_fps(sdev->sensor);
|
||||
if (result == BMKT_SUCCESS)
|
||||
{
|
||||
fp_info("Successfully initialized the FPS");
|
||||
}
|
||||
else if (result == BMKT_OPERATION_DENIED)
|
||||
{
|
||||
/* sensor already intialized...allow operations to continue */
|
||||
fp_info("FPS already initialized");
|
||||
result = BMKT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_err("Failed to initialize the FPS: %d", result);
|
||||
goto bmkt_cleanup;
|
||||
}
|
||||
|
||||
fp_dev_set_instance_data(dev, sdev);
|
||||
/* Notify open complete */
|
||||
fpi_drvcb_open_complete(dev, 0);
|
||||
return result;
|
||||
|
||||
bmkt_cleanup:
|
||||
ret = bmkt_close(sdev->sensor);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to close bmkt sensor: %d", ret);
|
||||
goto cleanup;
|
||||
}
|
||||
bmkt_exit(sdev->ctx);
|
||||
g_free(sdev);
|
||||
|
||||
cleanup:
|
||||
fpi_drvcb_open_complete(dev, 1);
|
||||
return result;
|
||||
}
|
||||
static void dev_exit(struct fp_dev *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
ret = bmkt_close(sdev->sensor);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to close bmkt sensor: %d", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
bmkt_exit(sdev->ctx);
|
||||
|
||||
g_free(sdev);
|
||||
fpi_drvcb_close_complete(dev);
|
||||
}
|
||||
|
||||
static gboolean rand_string(char *str, size_t size)
|
||||
{
|
||||
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
srand(time(NULL));
|
||||
if (size) {
|
||||
--size;
|
||||
for (size_t n = 0; n < size; n++) {
|
||||
int key = rand() % (int) (sizeof charset - 1);
|
||||
str[n] = charset[key];
|
||||
}
|
||||
str[size] = '\0';
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define TEMPLATE_ID_SIZE 20
|
||||
|
||||
static int del_enrolled_user_resp(bmkt_response_t *resp, void *ctx)
|
||||
{
|
||||
bmkt_del_user_resp_t *del_user_resp = &resp->response.del_user_resp;
|
||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
|
||||
switch (resp->response_id)
|
||||
{
|
||||
case BMKT_RSP_DELETE_PROGRESS:
|
||||
fp_info("Deleting Enrolled Users is %d%% complete",
|
||||
del_user_resp->progress);
|
||||
break;
|
||||
case BMKT_RSP_DEL_USER_FP_FAIL:
|
||||
fp_info("Failed to delete enrolled user: %d", resp->result);
|
||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
||||
if(sdev->state == SYNA_STATE_DELETE)
|
||||
{
|
||||
/* Return result complete when record doesn't exist, otherwise host data
|
||||
won't be deleted. */
|
||||
if(resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
||||
fpi_drvcb_delete_complete(dev, FP_DELETE_COMPLETE);
|
||||
else
|
||||
fpi_drvcb_delete_complete(dev, FP_DELETE_FAIL);
|
||||
}
|
||||
break;
|
||||
case BMKT_RSP_DEL_USER_FP_OK:
|
||||
fp_info("Successfully deleted enrolled user");
|
||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
||||
if(sdev->state == SYNA_STATE_DELETE)
|
||||
{
|
||||
fpi_drvcb_delete_complete(dev, FP_DELETE_COMPLETE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int enroll_start(struct fp_dev *dev)
|
||||
{
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
int result = 0;
|
||||
char userid[TEMPLATE_ID_SIZE + 1];
|
||||
|
||||
fp_info("enroll_start");
|
||||
|
||||
|
||||
rand_string(userid, TEMPLATE_ID_SIZE);
|
||||
|
||||
int useridlength =0;
|
||||
int finger_id;
|
||||
|
||||
finger_id = 1;
|
||||
useridlength = strlen(userid);
|
||||
|
||||
sdev->state = SYNA_STATE_ENROLL;
|
||||
|
||||
result = bmkt_enroll(sdev->sensor, userid, useridlength,
|
||||
finger_id, enroll_response, dev);
|
||||
if (result)
|
||||
{
|
||||
fp_err("Failed to enroll finger: %d", result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int enroll_stop(struct fp_dev *dev)
|
||||
{
|
||||
fp_info("syna enroll stop");
|
||||
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
sdev->state = SYNA_STATE_IDLE;
|
||||
fpi_drvcb_enroll_stopped(dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int verify_response(bmkt_response_t *resp, void *ctx)
|
||||
{
|
||||
bmkt_verify_resp_t *verify_resp = &resp->response.verify_resp;
|
||||
struct fp_dev *dev=(struct fp_dev *)ctx;
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
|
||||
switch (resp->response_id)
|
||||
{
|
||||
case BMKT_RSP_VERIFY_READY:
|
||||
{
|
||||
fp_info("Place Finger on the Sensor!");
|
||||
fpi_drvcb_verify_started(dev, 0);
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_CAPTURE_COMPLETE:
|
||||
{
|
||||
fp_info("Fingerprint image capture complete!");
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_VERIFY_FAIL:
|
||||
{
|
||||
fp_err("Verify has failed!: %d", resp->result);
|
||||
if(resp->result == BMKT_SENSOR_STIMULUS_ERROR || resp->result == BMKT_FP_NO_MATCH)
|
||||
{
|
||||
sdev->state = SYNA_STATE_VERIFY_DELAY_RESULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
||||
fpi_drvcb_report_verify_result(dev, FP_VERIFY_NO_MATCH, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BMKT_RSP_VERIFY_OK:
|
||||
{
|
||||
fp_info("Verify was successful! for user: %s finger: %d score: %f",
|
||||
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
|
||||
bmkt_op_set_state(sdev->sensor, BMKT_OP_STATE_COMPLETE);
|
||||
fpi_drvcb_report_verify_result(dev, FP_VERIFY_MATCH, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int delete_finger(struct fp_dev *dev)
|
||||
{
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
int result = 0;
|
||||
struct fp_print_data *print = fpi_dev_get_delete_data(dev);;
|
||||
struct fp_print_data_item *item = print->prints->data;
|
||||
struct syna_mis_print_data *print_data;
|
||||
bmkt_user_id_t user;
|
||||
|
||||
if(item->length != sizeof(struct syna_mis_print_data))
|
||||
{
|
||||
fp_err("print data is incorrect !");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
print_data = (struct syna_mis_print_data *)item->data;
|
||||
|
||||
memset(&user, 0, sizeof(bmkt_user_id_t));
|
||||
memcpy(user.user_id, print_data->user_id, sizeof(print_data->user_id));
|
||||
|
||||
fp_info("delete finger !");
|
||||
|
||||
user.user_id_len = strlen(user.user_id);
|
||||
if (user.user_id_len <= 0 || user.user_id[0] == ' ')
|
||||
{
|
||||
fp_err("Invalid user name.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sdev->state = SYNA_STATE_DELETE;
|
||||
result = bmkt_delete_enrolled_user(sdev->sensor, 1, print_data->user_id,
|
||||
user.user_id_len, del_enrolled_user_resp, dev);
|
||||
if (result != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to delete enrolled user: %d", result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
return -1;
|
||||
}
|
||||
static int verify_start(struct fp_dev *dev)
|
||||
{
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
int result = 0;
|
||||
struct fp_print_data *print = fpi_dev_get_verify_data(dev);;
|
||||
struct fp_print_data_item *item = print->prints->data;
|
||||
struct syna_mis_print_data *print_data;
|
||||
bmkt_user_id_t user;
|
||||
|
||||
if(item->length != sizeof(struct syna_mis_print_data))
|
||||
{
|
||||
fp_err("print data is incorrect !");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
print_data = (struct syna_mis_print_data *)item->data;
|
||||
|
||||
memset(&user, 0, sizeof(bmkt_user_id_t));
|
||||
memcpy(user.user_id, print_data->user_id, sizeof(print_data->user_id));
|
||||
|
||||
fp_info("syna verify_start !");
|
||||
|
||||
user.user_id_len = strlen(user.user_id);
|
||||
if (user.user_id_len <= 0 || user.user_id[0] == ' ')
|
||||
{
|
||||
fp_err("Invalid user name.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sdev->state = SYNA_STATE_VERIFY;
|
||||
result = bmkt_verify(sdev->sensor, &user, verify_response, dev);
|
||||
if (result != BMKT_SUCCESS)
|
||||
{
|
||||
fp_err("Failed to verify finger: %d", result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
fpi_drvcb_verify_started(dev, 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int verify_stop(struct fp_dev *dev, gboolean iterating)
|
||||
{
|
||||
fp_info("syna verify_stop");
|
||||
|
||||
synaptics_dev *sdev = FP_INSTANCE_DATA(dev);
|
||||
sdev->state = SYNA_STATE_IDLE;
|
||||
fpi_drvcb_verify_stopped(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct fp_driver synaptics_driver = {
|
||||
.id = SYNAPTICS_ID,
|
||||
.name = FP_COMPONENT,
|
||||
.full_name = SYNAPTICS_DRIVER_FULLNAME,
|
||||
.id_table = id_table,
|
||||
.scan_type = FP_SCAN_TYPE_PRESS,
|
||||
.open = dev_init,
|
||||
.close = dev_exit,
|
||||
.enroll_start = enroll_start,
|
||||
.enroll_stop = enroll_stop,
|
||||
.verify_start = verify_start,
|
||||
.verify_stop = verify_stop,
|
||||
.delete_finger = delete_finger,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __synaptics_h__
|
||||
#define __synaptics_h__
|
||||
|
||||
#define SYNAPTICS_VENDOR_ID 0x06cb
|
||||
#define SYNAPTICS_PRODUCT_ID_A9 0x00a9
|
||||
|
||||
/* Number of enroll stages */
|
||||
#define ENROLL_SAMPLES 12
|
||||
|
||||
#define SYNAPTICS_DRIVER_FULLNAME "Synaptics Sensors"
|
||||
#include "bmkt.h"
|
||||
#include "bmkt_response.h"
|
||||
|
||||
|
||||
struct syna_enroll_resp_data
|
||||
{
|
||||
int progress;
|
||||
};
|
||||
typedef enum syna_state
|
||||
{
|
||||
SYNA_STATE_UNINIT = 0,
|
||||
SYNA_STATE_IDLE ,
|
||||
SYNA_STATE_ENROLL ,
|
||||
SYNA_STATE_IDENTIFY ,
|
||||
SYNA_STATE_IDENTIFY_DELAY_RESULT ,
|
||||
SYNA_STATE_VERIFY ,
|
||||
SYNA_STATE_VERIFY_DELAY_RESULT ,
|
||||
SYNA_STATE_DELETE ,
|
||||
} syna_state_t;
|
||||
|
||||
typedef struct synaptics_dev_s
|
||||
{
|
||||
bmkt_ctx_t *ctx;
|
||||
bmkt_sensor_t *sensor;
|
||||
struct syna_enroll_resp_data enroll_resp_data;
|
||||
gboolean isFingerOnSensor;
|
||||
syna_state_t state;
|
||||
}synaptics_dev;
|
||||
|
||||
#endif //__synaptics_h__
|
||||
@@ -1,386 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "bmkt_internal.h"
|
||||
#include "sensor.h"
|
||||
#include "drivers_api.h"
|
||||
|
||||
|
||||
#define USB_ASYNC_MESSAGE_PENDING 0x4
|
||||
|
||||
static void usb_int_callback(struct libusb_transfer *transfer)
|
||||
{
|
||||
bmkt_usb_transport_t *usb_xport = (bmkt_usb_transport_t *)transfer->user_data;
|
||||
|
||||
#ifdef TRANSPORT_DEBUG
|
||||
bmkt_dbg_log("INTERRUPT: (%d) ", transfer->actual_length);
|
||||
print_buffer(transfer->buffer, transfer->actual_length);
|
||||
#endif
|
||||
|
||||
if (transfer->buffer[0] & USB_ASYNC_MESSAGE_PENDING)
|
||||
{
|
||||
libusb_free_transfer(transfer);
|
||||
bmkt_op_next_state(usb_xport->sensor);
|
||||
}
|
||||
else
|
||||
libusb_submit_transfer(transfer);
|
||||
}
|
||||
|
||||
int usb_check_interrupt(bmkt_usb_transport_t *usb_xport)
|
||||
{
|
||||
int ret;
|
||||
struct libusb_transfer *interrupt_xfer;
|
||||
interrupt_xfer = libusb_alloc_transfer(0);
|
||||
if (interrupt_xfer == NULL)
|
||||
{
|
||||
return BMKT_GENERAL_ERROR;
|
||||
}
|
||||
|
||||
libusb_fill_interrupt_transfer(interrupt_xfer, usb_xport->handle, USB_EP_INTERRUPT,
|
||||
usb_xport->interrupt_data, sizeof(usb_xport->interrupt_data), usb_int_callback, usb_xport, 0);
|
||||
|
||||
ret = libusb_submit_transfer(interrupt_xfer);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
libusb_free_transfer(interrupt_xfer);
|
||||
if (ret == LIBUSB_ERROR_NO_DEVICE)
|
||||
{
|
||||
return BMKT_SENSOR_MALFUNCTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
return BMKT_GENERAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int usb_open(bmkt_usb_transport_t *usb_xport)
|
||||
{
|
||||
int ret;
|
||||
struct libusb_config_descriptor *configDesc;
|
||||
const struct libusb_interface *iface;
|
||||
const struct libusb_interface_descriptor *ifaceDesc;
|
||||
const struct libusb_endpoint_descriptor *endpointDesc;
|
||||
int config;
|
||||
int i;
|
||||
|
||||
usb_xport->device = libusb_get_device(usb_xport->handle);
|
||||
|
||||
ret = libusb_reset_device(usb_xport->handle);
|
||||
if (ret)
|
||||
{
|
||||
bmkt_dbg_log("Failed to reset device\n");
|
||||
}
|
||||
|
||||
ret = libusb_get_config_descriptor(usb_xport->device, USB_DEFAULT_CONFIGURATION, &configDesc);
|
||||
if (ret)
|
||||
{
|
||||
ret = BMKT_SENSOR_MALFUNCTION;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = libusb_get_configuration(usb_xport->handle, &config);
|
||||
if (ret)
|
||||
{
|
||||
ret = BMKT_SENSOR_MALFUNCTION;
|
||||
goto free_config;
|
||||
}
|
||||
|
||||
if (configDesc->bConfigurationValue != config)
|
||||
{
|
||||
ret = libusb_set_configuration(usb_xport->handle, config);
|
||||
if (ret)
|
||||
{
|
||||
ret = BMKT_SENSOR_MALFUNCTION;
|
||||
goto free_config;
|
||||
}
|
||||
}
|
||||
|
||||
ret = libusb_kernel_driver_active(usb_xport->handle, 0);
|
||||
if (ret == 1)
|
||||
{
|
||||
bmkt_err_log("Failed to detect kernel driver\n");
|
||||
ret = BMKT_SENSOR_MALFUNCTION;
|
||||
goto free_config;
|
||||
}
|
||||
|
||||
ret = libusb_claim_interface(usb_xport->handle, USB_DEFAULT_INTERFACE);
|
||||
if (ret)
|
||||
{
|
||||
ret = BMKT_SENSOR_MALFUNCTION;
|
||||
goto free_config;
|
||||
}
|
||||
|
||||
iface = configDesc->interface + USB_DEFAULT_INTERFACE;
|
||||
ifaceDesc = iface->altsetting + USB_DEFAULT_ALT_SETTING;
|
||||
endpointDesc = ifaceDesc->endpoint;
|
||||
|
||||
for (i = 0; i < ifaceDesc->bNumEndpoints; i++)
|
||||
{
|
||||
ret = libusb_clear_halt(usb_xport->handle, endpointDesc->bEndpointAddress);
|
||||
if (ret)
|
||||
{
|
||||
ret = BMKT_SENSOR_MALFUNCTION;
|
||||
goto free_config;
|
||||
}
|
||||
++endpointDesc;
|
||||
}
|
||||
|
||||
free_config:
|
||||
libusb_free_config_descriptor(configDesc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_close(bmkt_usb_transport_t *usb_xport)
|
||||
{
|
||||
if (usb_xport->handle)
|
||||
{
|
||||
libusb_release_interface(usb_xport->handle, USB_DEFAULT_INTERFACE);
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
void usb_in_cb(struct libusb_transfer *transfer)
|
||||
{
|
||||
uint8_t *resp_buf;
|
||||
int resp_len;
|
||||
bmkt_msg_resp_t msg_resp;
|
||||
bmkt_usb_transport_t *usb_xport = (bmkt_usb_transport_t *)transfer->user_data;
|
||||
|
||||
#ifdef TRANSPORT_DEBUG
|
||||
bmkt_dbg_log("RX_ASYNC: (%d) ", transfer->actual_length);
|
||||
print_buffer(transfer->buffer, transfer->actual_length);
|
||||
#endif
|
||||
|
||||
resp_buf = transfer->buffer;
|
||||
resp_len = transfer->actual_length;
|
||||
bmkt_sensor_handle_response(usb_xport->sensor, resp_buf, resp_len, &msg_resp);
|
||||
libusb_free_transfer(transfer);
|
||||
|
||||
bmkt_op_next_state(usb_xport->sensor);
|
||||
}
|
||||
|
||||
void usb_out_cb(struct libusb_transfer *transfer)
|
||||
{
|
||||
|
||||
bmkt_usb_transport_t *usb_xport = (bmkt_usb_transport_t *)transfer->user_data;
|
||||
|
||||
libusb_free_transfer(transfer);
|
||||
bmkt_op_next_state(usb_xport->sensor);
|
||||
|
||||
}
|
||||
|
||||
static int bulk_transfer_async(bmkt_usb_transport_t *usb_xport, uint8_t *buf, int size, uint8_t endpoint,
|
||||
int *transferred, uint32_t timeout, libusb_transfer_cb_fn callback)
|
||||
{
|
||||
int ret;
|
||||
struct libusb_transfer *transfer;
|
||||
|
||||
#ifdef TRANSPORT_DEBUG
|
||||
if (!(endpoint & 0x80))
|
||||
{
|
||||
bmkt_dbg_log("TX2: (%d) ", size);
|
||||
print_buffer(buf, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
transfer = libusb_alloc_transfer(0);
|
||||
libusb_fill_bulk_transfer( transfer, usb_xport->handle, endpoint,
|
||||
buf, size, callback, usb_xport, 0);
|
||||
|
||||
ret = libusb_submit_transfer(transfer);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
libusb_free_transfer(transfer);
|
||||
if (ret == LIBUSB_ERROR_NO_DEVICE)
|
||||
{
|
||||
return BMKT_SENSOR_MALFUNCTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
return BMKT_GENERAL_ERROR;
|
||||
}
|
||||
}
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int bulk_transfer(bmkt_usb_transport_t *usb_xport, uint8_t *buf, int size, uint8_t endpoint,
|
||||
int *transferred, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef TRANSPORT_DEBUG
|
||||
if (!(endpoint & 0x80))
|
||||
{
|
||||
bmkt_dbg_log("TX: (%d) ", size);
|
||||
print_buffer(buf, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = libusb_bulk_transfer(usb_xport->handle, endpoint, buf, size, transferred, timeout);
|
||||
if (ret)
|
||||
{
|
||||
bmkt_warn_log("libusb_bulk_transfer: bulk transfer failed: %d\n", ret);
|
||||
if (ret == LIBUSB_ERROR_TIMEOUT)
|
||||
{
|
||||
return BMKT_OP_TIME_OUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return BMKT_SENSOR_MALFUNCTION;
|
||||
}
|
||||
}
|
||||
bmkt_dbg_log("transferred: %d\n", *transferred);
|
||||
|
||||
#ifdef TRANSPORT_DEBUG
|
||||
if (endpoint & 0x80)
|
||||
{
|
||||
bmkt_dbg_log("RX: (%d) ", *transferred);
|
||||
print_buffer(buf, *transferred);
|
||||
}
|
||||
#endif
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int usb_send_command(bmkt_usb_transport_t *usb_xport, int len)
|
||||
{
|
||||
int ret;
|
||||
int tx_len = 0;
|
||||
|
||||
ret = bulk_transfer_async(usb_xport, usb_xport->transfer, len, USB_EP_REQUEST, &tx_len, 0, usb_out_cb);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("Failed to send usb command\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int usb_get_command_buffer(bmkt_usb_transport_t *usb_xport, uint8_t **cmd, int *len)
|
||||
{
|
||||
|
||||
*len = BMKT_MAX_TRANSFER_LEN;
|
||||
*cmd = usb_xport->transfer;
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int usb_get_response_buffer(bmkt_usb_transport_t *usb_xport, uint8_t **resp, int *len)
|
||||
{
|
||||
*len = BMKT_MAX_TRANSFER_LEN;
|
||||
*resp = usb_xport->transfer;
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int usb_receive_resp_async(bmkt_usb_transport_t *usb_xport, int *len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*len = BMKT_MAX_TRANSFER_LEN;
|
||||
|
||||
/* Check to make sure the buffer is clear */
|
||||
memset(usb_xport->transfer, 0, BMKT_MAX_TRANSFER_LEN);
|
||||
|
||||
ret = bulk_transfer_async(usb_xport, usb_xport->transfer, *len, USB_EP_REPLY, len, 0, usb_in_cb);
|
||||
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("Failed to send usb command\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int usb_receive_resp(bmkt_usb_transport_t *usb_xport, int *len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*len = BMKT_MAX_TRANSFER_LEN;
|
||||
|
||||
/* Check to make sure the buffer is clear */
|
||||
memset(usb_xport->transfer, 0, BMKT_MAX_TRANSFER_LEN);
|
||||
|
||||
ret = bulk_transfer(usb_xport, usb_xport->transfer, *len, USB_EP_REPLY, len, 0);
|
||||
|
||||
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("Failed to send usb command\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int usb_send_command_sync(bmkt_usb_transport_t *usb_xport, int len, uint8_t **resp_buf,
|
||||
int *resp_len)
|
||||
{
|
||||
int ret;
|
||||
int tx_len = 0;
|
||||
|
||||
ret = bulk_transfer(usb_xport, usb_xport->transfer, len, USB_EP_REQUEST, &tx_len, 0);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("Failed to send usb command\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check to make sure the buffer is clear */
|
||||
memset(usb_xport->transfer, 0, BMKT_MAX_TRANSFER_LEN);
|
||||
|
||||
ret = bulk_transfer(usb_xport, usb_xport->transfer, *resp_len, USB_EP_REPLY, resp_len, 0);
|
||||
if (ret != BMKT_SUCCESS)
|
||||
{
|
||||
bmkt_dbg_log("Failed to send usb command\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*resp_buf = usb_xport->transfer;
|
||||
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
int usb_reset(bmkt_usb_transport_t *usb_xport)
|
||||
{
|
||||
return BMKT_OPERATION_DENIED;
|
||||
}
|
||||
|
||||
int usb_release_command_buffer(bmkt_usb_transport_t *usb_xport)
|
||||
{
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
int usb_release_response_buffer(bmkt_usb_transport_t *usb_xport)
|
||||
{
|
||||
return BMKT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _USB_TRANSPORT_H_
|
||||
#define _USB_TRANSPORT_H_
|
||||
|
||||
#include "bmkt_internal.h"
|
||||
#include "libusb-1.0/libusb.h"
|
||||
|
||||
|
||||
|
||||
#define BMKT_MAX_TRANSFER_LEN 263 + 1 /* SPI Header */ + 2 /* VCSFW header */
|
||||
|
||||
#define BMKT_XPORT_INT_NONE 0x0
|
||||
#define BMKT_XPORT_INT_RESPONSE 0x1
|
||||
#define BMKT_XPORT_INT_FINGER 0x2
|
||||
#define BMKT_XPORT_INT_ASYNC 0x4
|
||||
|
||||
#define USB_DEFAULT_CONFIGURATION 0
|
||||
#define USB_DEFAULT_INTERFACE 0
|
||||
#define USB_DEFAULT_ALT_SETTING 0
|
||||
|
||||
#define USB_EP_REQUEST 0x01
|
||||
#define USB_EP_REPLY 0x81
|
||||
#define USB_EP_FINGERPRINT 0x82
|
||||
#define USB_EP_INTERRUPT 0x83
|
||||
|
||||
#define USB_INTERRUPT_DATA_SIZE 7
|
||||
|
||||
|
||||
typedef struct bmkt_usb_transport
|
||||
{
|
||||
libusb_context *ctx;
|
||||
libusb_device *device;
|
||||
libusb_device_handle *handle;
|
||||
uint8_t interrupt_data[USB_INTERRUPT_DATA_SIZE];
|
||||
bmkt_sensor_t *sensor;
|
||||
uint8_t transfer[BMKT_MAX_TRANSFER_LEN];
|
||||
} bmkt_usb_transport_t;
|
||||
|
||||
|
||||
int usb_release_command_buffer(bmkt_usb_transport_t *xport);
|
||||
int usb_release_response_buffer(bmkt_usb_transport_t *xport);
|
||||
|
||||
|
||||
|
||||
|
||||
int usb_open(bmkt_usb_transport_t *xport);
|
||||
int usb_close(bmkt_usb_transport_t *xport);
|
||||
int usb_send_command(bmkt_usb_transport_t *xport, int len);
|
||||
int usb_get_command_buffer(bmkt_usb_transport_t *xport, uint8_t **cmd, int *len);
|
||||
int usb_get_response_buffer(bmkt_usb_transport_t *xport, uint8_t **resp, int *len);
|
||||
int usb_receive_resp(bmkt_usb_transport_t *xport, int *len);
|
||||
|
||||
int usb_send_command_sync(bmkt_usb_transport_t *xport, int len, uint8_t **resp_buf,
|
||||
int *resp_len);
|
||||
int usb_receive_resp_async(bmkt_usb_transport_t *usb_xport, int *len);
|
||||
int usb_check_interrupt(bmkt_usb_transport_t *usb_xport);
|
||||
|
||||
|
||||
#endif /* _USB_TRANSPORT_H_ */
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Synaptics Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "bmkt_internal.h"
|
||||
#include "sensor.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-zero-length"
|
||||
void print_buffer(uint8_t *buf, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
bmkt_dbg_log("0x%02x ", buf[i]);
|
||||
if ((i % 16) == 15)
|
||||
{
|
||||
bmkt_dbg_log("");
|
||||
}
|
||||
}
|
||||
bmkt_dbg_log("");
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
uint32_t extract32(const uint8_t *buf, int *offset)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
int off = 0;
|
||||
if (offset)
|
||||
{
|
||||
off = *offset;
|
||||
}
|
||||
ret = GUINT32_FROM_LE(*(uint32_t*)(buf + off));
|
||||
if (offset)
|
||||
{
|
||||
*offset += 4;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t extract16(const uint8_t *buf, int *offset)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
int off = 0;
|
||||
if (offset)
|
||||
{
|
||||
off = *offset;
|
||||
}
|
||||
ret = GUINT16_FROM_LE(*(uint16_t*)(buf + off));
|
||||
if (offset)
|
||||
{
|
||||
*offset += 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t extract8(const uint8_t *buf, int *offset)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
int off = 0;
|
||||
if (offset)
|
||||
{
|
||||
off = *offset;
|
||||
}
|
||||
ret = *(buf + off);
|
||||
if (offset)
|
||||
{
|
||||
*offset += 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -1268,7 +1268,7 @@ static void initsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
||||
fpi_ssm_start(sdev->loopsm, loopsm_complete);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
fpi_ssm *ssm = NULL;
|
||||
|
||||
@@ -377,7 +377,7 @@ static void start_capture(struct fp_img_dev *dev)
|
||||
fpi_ssm_start(ssm, capture_sm_complete);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -567,7 +567,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d
|
||||
start_capture(dev);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1161,20 +1161,10 @@ static void activate_initsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *us
|
||||
int r = fpi_ssm_get_error(ssm);
|
||||
fpi_ssm_free(ssm);
|
||||
|
||||
if (r) {
|
||||
fpi_imgdev_activate_complete(dev, r);
|
||||
return;
|
||||
}
|
||||
|
||||
r = execute_state_change(dev);
|
||||
fpi_imgdev_activate_complete(dev, r);
|
||||
}
|
||||
|
||||
/* FIXME: having state parameter here is kinda useless, will we ever
|
||||
* see a scenario where the parameter is useful so early on in the activation
|
||||
* process? asynchronity means that it'll only be used in a later function
|
||||
* call. */
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
fpi_ssm *ssm;
|
||||
@@ -1185,7 +1175,6 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
return r;
|
||||
|
||||
urudev->scanpwr_irq_timeouts = 0;
|
||||
urudev->activate_state = state;
|
||||
ssm = fpi_ssm_new(FP_DEV(dev), init_run_state, INIT_NUM_STATES, dev);
|
||||
fpi_ssm_start(ssm, activate_initsm_complete);
|
||||
return 0;
|
||||
|
||||
@@ -302,7 +302,7 @@ static void loopsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
||||
fpi_imgdev_deactivate_complete(dev);
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct v5s_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), loop_run_state,
|
||||
|
||||
@@ -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,
|
||||
@@ -684,7 +684,7 @@ static void dev_activate_callback(fpi_ssm *ssm, struct fp_dev *_dev, void *user_
|
||||
}
|
||||
|
||||
/* Activate device */
|
||||
static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *idev)
|
||||
{
|
||||
struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev));
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -1424,7 +1424,7 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
||||
}
|
||||
|
||||
/* Activate device */
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev));
|
||||
fpi_ssm *ssm;
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data)
|
||||
}
|
||||
|
||||
/* Activate device */
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
fpi_ssm *ssm;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -846,7 +846,7 @@ static void start_scan(struct fp_img_dev *dev)
|
||||
fp_dbg("ssm done, getting out");
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *dev)
|
||||
{
|
||||
struct vfs5011_data *data;
|
||||
|
||||
|
||||
@@ -77,9 +77,6 @@ enum fp_dev_state {
|
||||
DEV_STATE_CAPTURING,
|
||||
DEV_STATE_CAPTURE_DONE,
|
||||
DEV_STATE_CAPTURE_STOPPING,
|
||||
DEV_STATE_DELETING,
|
||||
DEV_STATE_DELETE_DONE,
|
||||
DEV_STATE_DELETE_STOPPING,
|
||||
};
|
||||
|
||||
struct fp_dev {
|
||||
@@ -99,9 +96,6 @@ struct fp_dev {
|
||||
/* read-only to drivers */
|
||||
struct fp_print_data *verify_data;
|
||||
|
||||
|
||||
struct fp_print_data *delete_data;
|
||||
|
||||
/* drivers should not mess with any of the below */
|
||||
enum fp_dev_state state;
|
||||
int __enroll_stage;
|
||||
@@ -129,8 +123,6 @@ struct fp_dev {
|
||||
void *capture_cb_data;
|
||||
fp_operation_stop_cb capture_stop_cb;
|
||||
void *capture_stop_cb_data;
|
||||
fp_delete_cb delete_cb;
|
||||
void *delete_cb_data;
|
||||
|
||||
/* FIXME: better place to put this? */
|
||||
struct fp_print_data **identify_gallery;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -680,58 +704,3 @@ API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev,
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_async_delete_finger:
|
||||
* @dev: the struct #fp_dev device
|
||||
* @data: data to delete. Must have been previously enrolled.
|
||||
* @callback: the callback to call when data deleted.
|
||||
* @user_data: user data to pass to the callback
|
||||
*
|
||||
* Request to delete data in sensor.
|
||||
*
|
||||
* Returns: 0 on success, non-zero on error
|
||||
*/
|
||||
|
||||
API_EXPORTED int fp_async_delete_finger(struct fp_dev *dev,
|
||||
struct fp_print_data *data, fp_delete_cb callback, void *user_data)
|
||||
{
|
||||
struct fp_driver *drv;
|
||||
int r;
|
||||
|
||||
g_return_val_if_fail(dev != NULL, -ENODEV);
|
||||
g_return_val_if_fail (callback != NULL, -EINVAL);
|
||||
|
||||
drv = dev->drv;
|
||||
|
||||
G_DEBUG_HERE();
|
||||
if (!drv->delete_finger)
|
||||
return -ENOTSUP;
|
||||
|
||||
dev->state = DEV_STATE_DELETING;
|
||||
dev->delete_cb = callback;
|
||||
dev->delete_cb_data = user_data;
|
||||
dev->delete_data = data;
|
||||
|
||||
r = drv->delete_finger(dev);
|
||||
if (r < 0) {
|
||||
dev->delete_cb = NULL;
|
||||
dev->state = DEV_STATE_ERROR;
|
||||
fp_err("failed to delete data, error %d", r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
/* Drivers call this when delete done */
|
||||
void fpi_drvcb_delete_complete(struct fp_dev *dev, int status)
|
||||
{
|
||||
fp_dbg("status %d", status);
|
||||
BUG_ON(dev->state != DEV_STATE_DELETING);
|
||||
dev->state = (status) ? DEV_STATE_ERROR : DEV_STATE_DELETE_DONE;
|
||||
if (dev->delete_cb)
|
||||
dev->delete_cb(dev, status, dev->delete_cb_data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,4 @@ void fpi_drvcb_report_verify_result(struct fp_dev *dev, int result,
|
||||
struct fp_img *img);
|
||||
void fpi_drvcb_verify_stopped(struct fp_dev *dev);
|
||||
|
||||
void fpi_drvcb_delete_complete(struct fp_dev *dev, int status);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -703,21 +703,6 @@ API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev)
|
||||
return dev->drv->identify_start != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_dev_supports_data_in_sensor:
|
||||
* @dev: the struct #fp_dev device
|
||||
*
|
||||
* Determines if a device is capable of storing print data in sensor.
|
||||
* Not all devices support this functionality.
|
||||
*
|
||||
* Returns: 1 if the device is capable of storing data in sensor, 0 otherwise.
|
||||
*/
|
||||
API_EXPORTED int fp_dev_supports_data_in_sensor(struct fp_dev *dev)
|
||||
{
|
||||
return dev->drv->delete_finger != NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fp_dev_get_img_width:
|
||||
* @dev: the struct #fp_dev device
|
||||
|
||||
@@ -87,7 +87,6 @@ struct fp_driver {
|
||||
int (*identify_stop)(struct fp_dev *dev, gboolean iterating);
|
||||
int (*capture_start)(struct fp_dev *dev);
|
||||
int (*capture_stop)(struct fp_dev *dev);
|
||||
int (*delete_finger)(struct fp_dev *dev);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -111,7 +110,7 @@ struct fp_img_driver {
|
||||
/* Device operations */
|
||||
int (*open)(struct fp_img_dev *dev, unsigned long driver_data);
|
||||
void (*close)(struct fp_img_dev *dev);
|
||||
int (*activate)(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
||||
int (*activate)(struct fp_img_dev *dev);
|
||||
int (*change_state)(struct fp_img_dev *dev, enum fp_imgdev_state state);
|
||||
void (*deactivate)(struct fp_img_dev *dev);
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
@@ -533,14 +536,14 @@ int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev)
|
||||
return height;
|
||||
}
|
||||
|
||||
static int dev_activate(struct fp_img_dev *imgdev, enum fp_imgdev_state state)
|
||||
static int dev_activate(struct fp_img_dev *imgdev)
|
||||
{
|
||||
struct fp_driver *drv = FP_DEV(imgdev)->drv;
|
||||
struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv);
|
||||
|
||||
if (!imgdrv->activate)
|
||||
return 0;
|
||||
return imgdrv->activate(imgdev, state);
|
||||
return imgdrv->activate(imgdev);
|
||||
}
|
||||
|
||||
static void dev_deactivate(struct fp_img_dev *imgdev)
|
||||
@@ -562,7 +565,7 @@ static int generic_acquire_start(struct fp_dev *dev, int action)
|
||||
imgdev->action_state = IMG_ACQUIRE_STATE_ACTIVATING;
|
||||
imgdev->enroll_stage = 0;
|
||||
|
||||
r = dev_activate(imgdev, IMGDEV_STATE_AWAIT_FINGER_ON);
|
||||
r = dev_activate(imgdev);
|
||||
if (r < 0)
|
||||
fp_err("activation failed with error %d", r);
|
||||
|
||||
|
||||
@@ -148,17 +148,3 @@ fpi_dev_get_verify_data(struct fp_dev *dev)
|
||||
{
|
||||
return dev->verify_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_dev_get_delete_data:
|
||||
* @dev: a struct #fp_dev
|
||||
*
|
||||
* Returns the delete data associated with @dev.
|
||||
* Returns: a struct #fp_print_data pointer or %NULL
|
||||
*/
|
||||
struct fp_print_data *
|
||||
fpi_dev_get_delete_data(struct fp_dev *dev)
|
||||
{
|
||||
return dev->delete_data;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,5 @@ libusb_device_handle *fpi_dev_get_usb_dev(struct fp_dev *dev);
|
||||
void fpi_dev_set_nr_enroll_stages(struct fp_dev *dev,
|
||||
int nr_enroll_stages);
|
||||
struct fp_print_data *fpi_dev_get_verify_data(struct fp_dev *dev);
|
||||
struct fp_print_data *fpi_dev_get_delete_data(struct fp_dev *dev);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
@@ -441,72 +441,6 @@ API_EXPORTED int fp_verify_finger(struct fp_dev *dev,
|
||||
return fp_verify_finger_img(dev, enrolled_print, NULL);
|
||||
}
|
||||
|
||||
struct sync_delete_data {
|
||||
gboolean populated;
|
||||
int result;
|
||||
};
|
||||
static void sync_delete_cb(struct fp_dev *dev, int result, void *user_data)
|
||||
{
|
||||
struct sync_delete_data *ddata = user_data;
|
||||
ddata->result = result;
|
||||
ddata->populated = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fp_delete_finger:
|
||||
* @dev: the struct #fp_dev device to perform the operation.
|
||||
* @enrolled_data: the id need to delete on sensor. This id is
|
||||
* returned in previously enrolled with a MIS device.
|
||||
*
|
||||
* Perform a delete data operation on sensor. When print data is stored on sensor,
|
||||
* this function is needed when host deletes enrolled finger.
|
||||
*
|
||||
* Returns: negative code on error, otherwise a code from #fp_delete_result
|
||||
*/
|
||||
|
||||
API_EXPORTED int fp_delete_finger(struct fp_dev *dev,
|
||||
struct fp_print_data *enrolled_data)
|
||||
{
|
||||
struct sync_delete_data *ddata;
|
||||
gboolean stopped = FALSE;
|
||||
int r;
|
||||
|
||||
if (!enrolled_data) {
|
||||
fp_err("no print given");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!fp_dev_supports_print_data(dev, enrolled_data)) {
|
||||
fp_err("print is not compatible with device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fp_dbg("to be handled by %s", dev->drv->name);
|
||||
ddata = g_malloc0(sizeof(struct sync_delete_data));
|
||||
r = fp_async_delete_finger(dev, enrolled_data, sync_delete_cb, ddata);
|
||||
if (r < 0) {
|
||||
fp_dbg("delete_finger error %d", r);
|
||||
g_free(ddata);
|
||||
return r;
|
||||
}
|
||||
|
||||
while (!ddata->populated) {
|
||||
r = fp_handle_events();
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = ddata->result;
|
||||
fp_dbg("delete_finger result %d", r);
|
||||
|
||||
out:
|
||||
g_free(ddata);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct sync_identify_data {
|
||||
gboolean populated;
|
||||
int result;
|
||||
|
||||
@@ -267,17 +267,12 @@ int fp_verify_finger(struct fp_dev *dev,
|
||||
struct fp_print_data *enrolled_print);
|
||||
|
||||
int fp_dev_supports_identification(struct fp_dev *dev);
|
||||
int fp_dev_supports_data_in_sensor(struct fp_dev *dev);
|
||||
|
||||
int fp_identify_finger_img(struct fp_dev *dev,
|
||||
struct fp_print_data **print_gallery, size_t *match_offset,
|
||||
struct fp_img **img);
|
||||
int fp_identify_finger(struct fp_dev *dev,
|
||||
struct fp_print_data **print_gallery, size_t *match_offset);
|
||||
|
||||
int fp_delete_finger(struct fp_dev *dev,
|
||||
struct fp_print_data *enrolled_print);
|
||||
|
||||
/* Data handling */
|
||||
int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger,
|
||||
struct fp_print_data **data) LIBFPRINT_DEPRECATED;
|
||||
@@ -456,22 +451,6 @@ int fp_async_capture_start(struct fp_dev *dev, int unconditional, fp_img_operati
|
||||
|
||||
int fp_async_capture_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data);
|
||||
|
||||
/**
|
||||
* fp_delete_result:
|
||||
* @FP_DELETE_COMPLETE: Delete completed successfully.
|
||||
* @FP_DELETE_FAIL: Delete failed
|
||||
*
|
||||
*/
|
||||
enum fp_delete_result {
|
||||
FP_DELETE_COMPLETE = 0,
|
||||
FP_DELETE_FAIL = 1,
|
||||
};
|
||||
|
||||
typedef void (*fp_delete_cb)(struct fp_dev *dev, int status, void *user_data);
|
||||
|
||||
int fp_async_delete_finger(struct fp_dev *dev, struct fp_print_data *data, fp_delete_cb callback, void *user_data);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,40 +1,18 @@
|
||||
libfprint_sources = [
|
||||
'fp_internal.h',
|
||||
'nbis-helpers.h',
|
||||
'drivers_api.h',
|
||||
'fpi-async.c',
|
||||
'fpi-async.h',
|
||||
'fpi-assembling.c',
|
||||
'fpi-assembling.h',
|
||||
'fpi-core.c',
|
||||
'fpi-core.h',
|
||||
'fpi-data.c',
|
||||
'fpi-data.h',
|
||||
'fpi-dev.c',
|
||||
'fpi-dev.h',
|
||||
'fpi-dev-img.c',
|
||||
'fpi-dev-img.h',
|
||||
'fpi-img.c',
|
||||
'fpi-img.h',
|
||||
'fpi-log.h',
|
||||
'fpi-ssm.c',
|
||||
'fpi-ssm.h',
|
||||
'fpi-sync.c',
|
||||
'fpi-poll.h',
|
||||
'fpi-poll.c',
|
||||
'fpi-usb.h',
|
||||
'fpi-usb.c',
|
||||
'drivers/driver_ids.h',
|
||||
]
|
||||
|
||||
nbis_sources = [
|
||||
'nbis/include/bozorth.h',
|
||||
'nbis/include/bz_array.h',
|
||||
'nbis/include/defs.h',
|
||||
'nbis/include/lfs.h',
|
||||
'nbis/include/log.h',
|
||||
'nbis/include/morph.h',
|
||||
'nbis/include/sunrast.h',
|
||||
'nbis/bozorth3/bozorth3.c',
|
||||
'nbis/bozorth3/bz_alloc.c',
|
||||
'nbis/bozorth3/bz_drvrs.c',
|
||||
@@ -74,16 +52,15 @@ aesx660 = false
|
||||
aes3k = false
|
||||
drivers_sources = []
|
||||
drivers_cflags = []
|
||||
|
||||
foreach driver: drivers
|
||||
if driver == 'upekts'
|
||||
drivers_sources += [ 'drivers/upekts.c' ]
|
||||
drivers_sources += [ 'drivers/upekts.c', 'drivers/upek_proto.c' ]
|
||||
endif
|
||||
if driver == 'upektc'
|
||||
drivers_sources += [ 'drivers/upektc.c', 'drivers/upektc.h', 'drivers/upek_proto.c', 'drivers/upek_proto.h' ]
|
||||
drivers_sources += [ 'drivers/upektc.c' ]
|
||||
endif
|
||||
if driver == 'upeksonly'
|
||||
drivers_sources += [ 'drivers/upeksonly.c', 'drivers/upeksonly.h' ]
|
||||
drivers_sources += [ 'drivers/upeksonly.c' ]
|
||||
endif
|
||||
if driver == 'uru4000'
|
||||
drivers_sources += [ 'drivers/uru4000.c' ]
|
||||
@@ -93,20 +70,20 @@ foreach driver: drivers
|
||||
aeslib = true
|
||||
endif
|
||||
if driver == 'aes1660'
|
||||
drivers_sources += [ 'drivers/aes1660.c', 'drivers/aes1660.h' ]
|
||||
drivers_sources += [ 'drivers/aes1660.c' ]
|
||||
aeslib = true
|
||||
aesx660 = true
|
||||
endif
|
||||
if driver == 'aes2501'
|
||||
drivers_sources += [ 'drivers/aes2501.c', 'drivers/aes2501.h' ]
|
||||
drivers_sources += [ 'drivers/aes2501.c' ]
|
||||
aeslib = true
|
||||
endif
|
||||
if driver == 'aes2550'
|
||||
drivers_sources += [ 'drivers/aes2550.c', 'drivers/aes2550.h' ]
|
||||
drivers_sources += [ 'drivers/aes2550.c' ]
|
||||
aeslib = true
|
||||
endif
|
||||
if driver == 'aes2660'
|
||||
drivers_sources += [ 'drivers/aes2660.c', 'drivers/aes2660.h' ]
|
||||
drivers_sources += [ 'drivers/aes2660.c' ]
|
||||
aeslib = true
|
||||
aesx660 = true
|
||||
endif
|
||||
@@ -120,9 +97,6 @@ foreach driver: drivers
|
||||
aeslib = true
|
||||
aes3k = true
|
||||
endif
|
||||
if driver == 'fdu2000'
|
||||
drivers_sources += [ 'drivers/fdu2000.c' ]
|
||||
endif
|
||||
if driver == 'vcom5s'
|
||||
drivers_sources += [ 'drivers/vcom5s.c' ]
|
||||
endif
|
||||
@@ -130,43 +104,33 @@ foreach driver: drivers
|
||||
drivers_sources += [ 'drivers/vfs101.c' ]
|
||||
endif
|
||||
if driver == 'vfs301'
|
||||
drivers_sources += [ 'drivers/vfs301.c', 'drivers/vfs301_proto.c', 'drivers/vfs301_proto.h', 'drivers/vfs301_proto_fragments.h' ]
|
||||
drivers_sources += [ 'drivers/vfs301.c', 'drivers/vfs301_proto.c' ]
|
||||
endif
|
||||
if driver == 'vfs5011'
|
||||
drivers_sources += [ 'drivers/vfs5011.c', 'drivers/vfs5011_proto.h' ]
|
||||
drivers_sources += [ 'drivers/vfs5011.c' ]
|
||||
endif
|
||||
if driver == 'upektc_img'
|
||||
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upektc_img.h', 'drivers/upek_proto.c', 'drivers/upek_proto.h' ]
|
||||
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ]
|
||||
endif
|
||||
if driver == 'etes603'
|
||||
drivers_sources += [ 'drivers/etes603.c' ]
|
||||
endif
|
||||
if driver == 'vfs0050'
|
||||
drivers_sources += [ 'drivers/vfs0050.c', 'drivers/vfs0050.h' ]
|
||||
drivers_sources += [ 'drivers/vfs0050.c' ]
|
||||
endif
|
||||
if driver == 'elan'
|
||||
drivers_sources += [ 'drivers/elan.c', 'drivers/elan.h' ]
|
||||
endif
|
||||
if driver == 'synaptics'
|
||||
drivers_sources += [
|
||||
'drivers/synaptics/synaptics.c',
|
||||
'drivers/synaptics/bmkt.c',
|
||||
'drivers/synaptics/util.c',
|
||||
'drivers/synaptics/bmkt_message.c',
|
||||
'drivers/synaptics/sensor.c',
|
||||
'drivers/synaptics/usb_transport.c',
|
||||
]
|
||||
drivers_sources += [ 'drivers/elan.c' ]
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if aeslib
|
||||
drivers_sources += [ 'drivers/aeslib.c', 'drivers/aeslib.h' ]
|
||||
drivers_sources += [ 'drivers/aeslib.c' ]
|
||||
endif
|
||||
if aesx660
|
||||
drivers_sources += ['drivers/aesx660.c', 'drivers/aesx660.h' ]
|
||||
drivers_sources += ['drivers/aesx660.c' ]
|
||||
endif
|
||||
if aes3k
|
||||
drivers_sources += ['drivers/aes3k.c', 'drivers/aes3k.h' ]
|
||||
drivers_sources += ['drivers/aes3k.c' ]
|
||||
endif
|
||||
|
||||
other_sources = []
|
||||
@@ -191,7 +155,6 @@ libfprint_sources += configure_file(input: 'empty_file',
|
||||
])
|
||||
|
||||
deps = [ mathlib_dep, glib_dep, libusb_dep, nss_dep, imaging_dep ]
|
||||
|
||||
libfprint = library('fprint',
|
||||
libfprint_sources + drivers_sources + nbis_sources + other_sources,
|
||||
soversion: soversion,
|
||||
|
||||
12
meson.build
12
meson.build
@@ -1,5 +1,5 @@
|
||||
project('libfprint', [ 'c', 'cpp' ],
|
||||
version: '0.99.0',
|
||||
version: '1.0',
|
||||
license: 'LGPLv2.1+',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
@@ -27,7 +27,9 @@ common_cflags = cc.get_supported_arguments([
|
||||
'-Wstrict-prototypes',
|
||||
'-Werror-implicit-function-declaration',
|
||||
'-Wno-pointer-sign',
|
||||
'-Wshadow'
|
||||
'-Wshadow',
|
||||
'-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_50',
|
||||
'-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_50',
|
||||
])
|
||||
|
||||
# maintaining compatibility with the previous libtool versioning
|
||||
@@ -39,14 +41,14 @@ revision = 0
|
||||
libversion = '@0@.@1@.@2@'.format(soversion, current, revision)
|
||||
|
||||
# Dependencies
|
||||
glib_dep = dependency('glib-2.0', version: '>= 2.28')
|
||||
glib_dep = dependency('glib-2.0', version: '>= 2.50')
|
||||
libusb_dep = dependency('libusb-1.0', version: '>= 0.9.1')
|
||||
mathlib_dep = cc.find_library('m', required: false)
|
||||
|
||||
# Drivers
|
||||
drivers = get_option('drivers').split(',')
|
||||
all_drivers = [ 'upekts', 'upektc', 'upeksonly', 'vcom5s', 'uru4000', 'aes1610', 'aes1660', 'aes2501', 'aes2550', 'aes2660', 'aes3500', 'aes4000', 'vfs101', 'vfs301', 'vfs5011', 'upektc_img', 'etes603', 'vfs0050', 'elan', 'synaptics' ]
|
||||
primitive_drivers = [ 'upekts', 'synaptics' ]
|
||||
all_drivers = [ 'upekts', 'upektc', 'upeksonly', 'vcom5s', 'uru4000', 'aes1610', 'aes1660', 'aes2501', 'aes2550', 'aes2660', 'aes3500', 'aes4000', 'vfs101', 'vfs301', 'vfs5011', 'upektc_img', 'etes603', 'vfs0050', 'elan' ]
|
||||
primitive_drivers = [ 'upekts' ]
|
||||
|
||||
if drivers == [ 'all' ]
|
||||
drivers = all_drivers
|
||||
|
||||
Reference in New Issue
Block a user