klte: Use new Fingerprint Hal without ValidityService
* Use a fully OSS FPS stack to remove dependency on a service to register fingerprints and hacked up touchwiz libs from Samsung Change-Id: I66ae7fc807a213befdf77d0f09d38f2fbe01df61
This commit is contained in:
parent
2de5ba9107
commit
2f41fd2d2f
41 changed files with 2191 additions and 1884 deletions
|
@ -224,14 +224,6 @@ vendor/lib/libwvm.so
|
|||
vendor/lib/libWVStreamControlAPI_L1.so
|
||||
vendor/lib/mediadrm/libwvdrmengine.so
|
||||
|
||||
# Fingerprint
|
||||
bin/vcsFPService
|
||||
lib/libfpasmtztransport.so
|
||||
lib/libvalAuth.so
|
||||
lib/libvcsfp.so
|
||||
lib/libvfmClient.so
|
||||
lib/libvfmtztransport.so
|
||||
|
||||
# Graphics
|
||||
vendor/lib/egl/eglsubAndroid.so
|
||||
vendor/lib/egl/libEGL_adreno.so
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# Copyright (C) 2016 The CyanogenMod Project
|
||||
# Copyright (C) 2016 The Mokee Project
|
||||
# Copyright (C) 2016 The CyanogenMod Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -21,8 +21,19 @@ include $(CLEAR_VARS)
|
|||
|
||||
LOCAL_MODULE := fingerprint.msm8974
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
|
||||
LOCAL_SRC_FILES := fingerprint.c
|
||||
LOCAL_SHARED_LIBRARIES := liblog
|
||||
LOCAL_SRC_FILES := \
|
||||
fingerprint.c \
|
||||
fingerprint_tz.c \
|
||||
QSEEComAPI.c \
|
||||
hash.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
external/sqlite/dist
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog \
|
||||
libsqlite
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
|
164
fingerprint/QSEEComAPI.c
Normal file
164
fingerprint/QSEEComAPI.c
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||
* may not use this file except in compliance with the License. You may
|
||||
* obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "Custom_QSEE"
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "QSEEComAPI.h"
|
||||
|
||||
struct qcom_keymaster_handle {
|
||||
void *libhandle;
|
||||
int (*QSEECom_start_app)(struct QSEECom_handle ** handle, const char* path,
|
||||
const char* appname, uint32_t size);
|
||||
int (*QSEECom_shutdown_app)(struct QSEECom_handle **handle);
|
||||
int (*QSEECom_send_cmd)(struct QSEECom_handle* handle, void *cbuf,
|
||||
uint32_t clen, void *rbuf, uint32_t rlen);
|
||||
int (*QSEECom_send_modified_cmd)(struct QSEECom_handle* handle, void *cbuf,
|
||||
uint32_t clen, void *rbuf, uint32_t rlen,
|
||||
struct QSEECom_ion_fd_info *ihandle);
|
||||
int (*QSEECom_set_bandwidth)(struct QSEECom_handle* handle, bool high);
|
||||
};
|
||||
typedef struct qcom_keymaster_handle qcom_keymaster_handle_t;
|
||||
|
||||
bool init = false;
|
||||
qcom_keymaster_handle_t* km_handle;
|
||||
int file_num = 0;
|
||||
|
||||
static int qcom_km_get_lib_sym(qcom_keymaster_handle_t* km_handle)
|
||||
{
|
||||
km_handle->libhandle = dlopen("libQSEEComAPI.so", RTLD_NOW);
|
||||
if ( km_handle->libhandle ) {
|
||||
*(void **)(&km_handle->QSEECom_start_app) =
|
||||
dlsym(km_handle->libhandle,"QSEECom_start_app");
|
||||
if (km_handle->QSEECom_start_app == NULL) {
|
||||
ALOGE("dlsym: Error Loading QSEECom_start_app");
|
||||
dlclose(km_handle->libhandle );
|
||||
km_handle->libhandle = NULL;
|
||||
return -1;
|
||||
}
|
||||
*(void **)(&km_handle->QSEECom_shutdown_app) =
|
||||
dlsym(km_handle->libhandle,"QSEECom_shutdown_app");
|
||||
if (km_handle->QSEECom_shutdown_app == NULL) {
|
||||
ALOGE("dlsym: Error Loading QSEECom_shutdown_app");
|
||||
dlclose(km_handle->libhandle );
|
||||
km_handle->libhandle = NULL;
|
||||
return -1;
|
||||
}
|
||||
*(void **)(&km_handle->QSEECom_send_cmd) =
|
||||
dlsym(km_handle->libhandle,"QSEECom_send_cmd");
|
||||
if (km_handle->QSEECom_send_cmd == NULL) {
|
||||
ALOGE("dlsym: Error Loading QSEECom_send_cmd");
|
||||
dlclose(km_handle->libhandle );
|
||||
km_handle->libhandle = NULL;
|
||||
return -1;
|
||||
}
|
||||
*(void **)(&km_handle->QSEECom_send_modified_cmd) =
|
||||
dlsym(km_handle->libhandle,"QSEECom_send_modified_cmd");
|
||||
if (km_handle->QSEECom_send_modified_cmd == NULL) {
|
||||
ALOGE("dlsym: Error Loading QSEECom_send_modified_cmd");
|
||||
dlclose(km_handle->libhandle );
|
||||
km_handle->libhandle = NULL;
|
||||
return -1;
|
||||
}
|
||||
*(void **)(&km_handle->QSEECom_set_bandwidth) =
|
||||
dlsym(km_handle->libhandle,"QSEECom_set_bandwidth");
|
||||
if (km_handle->QSEECom_set_bandwidth == NULL) {
|
||||
ALOGE("dlsym: Error Loading QSEECom_set_bandwidth");
|
||||
dlclose(km_handle->libhandle );
|
||||
km_handle->libhandle = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
ALOGE("failed to load qseecom library");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_qsee()
|
||||
{
|
||||
if (init) {
|
||||
return 0;
|
||||
}
|
||||
int ret = 0;
|
||||
km_handle = (qcom_keymaster_handle_t *)malloc(sizeof(qcom_keymaster_handle_t));
|
||||
if (km_handle == NULL) {
|
||||
ALOGE("Memalloc for keymaster handle failed");
|
||||
return -1;
|
||||
}
|
||||
km_handle->libhandle = NULL;
|
||||
ret = qcom_km_get_lib_sym(km_handle);
|
||||
if (ret) {
|
||||
free(km_handle);
|
||||
return -1;
|
||||
}
|
||||
init = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int QSEECom_start_app(struct QSEECom_handle **clnt_handle, const char *path,
|
||||
const char *fname, uint32_t sb_size)
|
||||
{
|
||||
init_qsee();
|
||||
int ret = 0;
|
||||
ret = (*km_handle->QSEECom_start_app)(clnt_handle,path,fname,sb_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int QSEECom_shutdown_app(struct QSEECom_handle **handle)
|
||||
{
|
||||
init_qsee();
|
||||
int ret = 0;
|
||||
ret = (*km_handle->QSEECom_shutdown_app)(handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int QSEECom_send_cmd(struct QSEECom_handle *handle, void *send_buf,
|
||||
uint32_t sbuf_len, void *rcv_buf, uint32_t rbuf_len)
|
||||
{
|
||||
init_qsee();
|
||||
int ret = 0;
|
||||
ret = (*km_handle->QSEECom_send_cmd)(handle,send_buf,sbuf_len,rcv_buf,rbuf_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int QSEECom_send_modified_cmd(struct QSEECom_handle *handle, void *send_buf,
|
||||
uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len,
|
||||
struct QSEECom_ion_fd_info *ifd_data)
|
||||
{
|
||||
init_qsee();
|
||||
int ret = 0;
|
||||
ret = (*km_handle->QSEECom_send_modified_cmd)(handle,send_buf,sbuf_len,resp_buf,rbuf_len,ifd_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int QSEECom_set_bandwidth(struct QSEECom_handle *handle, bool high)
|
||||
{
|
||||
init_qsee();
|
||||
int ret = 0;
|
||||
ret = (*km_handle->QSEECom_set_bandwidth)(handle,high);
|
||||
return ret;
|
||||
}
|
||||
|
299
fingerprint/QSEEComAPI.h
Normal file
299
fingerprint/QSEEComAPI.h
Normal file
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* Copyright (c) 2012, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||
* may not use this file except in compliance with the License. You may
|
||||
* obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __QSEECOMAPI_H_
|
||||
#define __QSEECOMAPI_H_
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Include Files
|
||||
* -------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define QSEECOM_ALIGN_SIZE 0x40
|
||||
#define QSEECOM_ALIGN_MASK (QSEECOM_ALIGN_SIZE - 1)
|
||||
#define QSEECOM_ALIGN(x) \
|
||||
((x + QSEECOM_ALIGN_SIZE) & (~QSEECOM_ALIGN_MASK))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Preprocessor Definitions and Constants
|
||||
* -------------------------------------------------------------------------*/
|
||||
/** The memory is locked and non-pageable */
|
||||
#define MEM_LOCKED 0x00000001
|
||||
/** The memory is marked non-cacheable */
|
||||
#define MEM_NON_CACHED 0x00000002
|
||||
|
||||
#define QSEECOM_APP_QUERY_FAILED -6
|
||||
#define QSEECOM_APP_NOT_LOADED -5
|
||||
#define QSEECOM_APP_ALREADY_LOADED -4
|
||||
#define QSEECOM_LISTENER_UNREGISTERED -3
|
||||
#define QSEECOM_LISTENER_ALREADY_REGISTERED -2
|
||||
#define QSEECOM_LISTENER_REGISTER_FAIL -1
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Type Declarations
|
||||
* -------------------------------------------------------------------------*/
|
||||
struct QSEECom_handle {
|
||||
unsigned char *ion_sbuffer;
|
||||
};
|
||||
|
||||
struct QSEECom_ion_fd_data {
|
||||
int32_t fd;
|
||||
uint32_t cmd_buf_offset;
|
||||
};
|
||||
|
||||
struct QSEECom_ion_fd_info {
|
||||
struct QSEECom_ion_fd_data data[4];
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Function Declarations and Documentation
|
||||
* -------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Open a handle to the QSEECom device.
|
||||
*
|
||||
* - Load a secure application. The application will be verified that it is
|
||||
* secure by digital signature verification.
|
||||
* Allocate memory for sending requests to the QSAPP
|
||||
*
|
||||
* Note/Comments:
|
||||
* There is a one-to-one relation for a HLOS client and a QSAPP;
|
||||
* meaning that only one app can communicate to a QSAPP at a time.
|
||||
*
|
||||
* Please note that there is difference between an application and a listener
|
||||
* service. A QSAPP must be loaded at the request of the HLOS,
|
||||
* and all requests are orginated by the HLOS client.
|
||||
* A listener service on the otherhand is started during start-up by a
|
||||
* daemon, qseecomd.
|
||||
*
|
||||
* A HLOS application may create mutiple handles to the QSAPP
|
||||
*
|
||||
* @param[in/out] handle The device handle
|
||||
* @param[in] fname The directory and filename to load.
|
||||
* @param[in] sb_size Size of the shared buffer memory for sending requests.
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_start_app(struct QSEECom_handle **clnt_handle, const char *path,
|
||||
const char *fname, uint32_t sb_size);
|
||||
|
||||
/**
|
||||
* @brief Close the application associated with the handle.
|
||||
*
|
||||
* - Unload a secure application. The driver will verify if there exists
|
||||
* any other applications that are communicating with the QSAPP to which
|
||||
* the "handle" is tied.
|
||||
* - De-allocate memory for sending requests to QSAPP.
|
||||
*
|
||||
* @param[in] handle The device handle
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_shutdown_app(struct QSEECom_handle **handle);
|
||||
|
||||
/**
|
||||
* @brief Open a handle to the QSEECom device.
|
||||
*
|
||||
* - Load an external elf. The elf will be verified that it is
|
||||
* secure by digital signature verification.
|
||||
*
|
||||
* A HLOS application may create mutiple opens (only one is permitted for the
|
||||
* app, but each listener service can open a unique device in the same HLOS app
|
||||
* /executable.
|
||||
* @param[in/out] handle The device handle
|
||||
* @param[in] fname The directory and filename to load.
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_load_external_elf(struct QSEECom_handle **clnt_handle, const char *path,
|
||||
const char *fname);
|
||||
|
||||
/**
|
||||
* @brief Close the external elf
|
||||
*
|
||||
* - Unload an external elf.
|
||||
*
|
||||
* @param[in] handle The device handle
|
||||
*
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_unload_external_elf(struct QSEECom_handle **handle);
|
||||
|
||||
/**
|
||||
* @brief Register an HLOS listener service. This allows messages from QSAPP
|
||||
* to be received.
|
||||
*
|
||||
* @param[in] handle The device handle
|
||||
* @param[in] lstnr_id The listener service identifier. This ID must be uniquely
|
||||
* assigned to avoid any collisions.
|
||||
* @param[in] sb_length Shared memory buffer between OS and QSE.
|
||||
* @param[in] flags Provide the shared memory flags attributes.
|
||||
*
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*
|
||||
*/
|
||||
int QSEECom_register_listener(struct QSEECom_handle **handle,
|
||||
uint32_t lstnr_id, uint32_t sb_length, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Unregister a listener service.
|
||||
*
|
||||
* @param[in] handle The device handle
|
||||
*
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_unregister_listener(struct QSEECom_handle *handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send QSAPP a "user" defined buffer (may contain some message/
|
||||
* command request) and receives a response from QSAPP in receive buffer.
|
||||
* The HLOS client writes to the send_buf, where QSAPP writes to the rcv_buf.
|
||||
* This is a blocking call.
|
||||
*
|
||||
* @param[in] handle The device handle
|
||||
* @param[in] send_buf The buffer to be sent.
|
||||
* If using ion_sbuffer, ensure this
|
||||
* QSEECOM_BUFFER_ALIGN'ed.
|
||||
* @param[in] sbuf_len The send buffer length
|
||||
* If using ion_sbuffer, ensure length is
|
||||
* multiple of QSEECOM_BUFFER_ALIGN.
|
||||
* @param[in] rcv_buf The QSEOS returned buffer.
|
||||
* If using ion_sbuffer, ensure this is
|
||||
* QSEECOM_BUFFER_ALIGN'ed.
|
||||
* @param[in] rbuf_len The returned buffer length.
|
||||
* If using ion_sbuffer, ensure length is
|
||||
* multiple of QSEECOM_BUFFER_ALIGN.
|
||||
* @param[in] rbuf_len The returned buffer length.
|
||||
*
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_send_cmd(struct QSEECom_handle *handle, void *send_buf,
|
||||
uint32_t sbuf_len, void *rcv_buf, uint32_t rbuf_len);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send QSAPP a "user" defined buffer (may contain some message/
|
||||
* command request) and receives a response from QSAPP in receive buffer.
|
||||
* This API is same as send_cmd except it takes in addition parameter,
|
||||
* "ifd_data". This "ifd_data" holds information (ion fd handle and
|
||||
* cmd_buf_offset) used for modifying data in the message in send_buf
|
||||
* at an offset. Essentailly, it has the ion fd handle information to
|
||||
* retrieve physical address and modify the message in send_buf at the
|
||||
* mentioned offset.
|
||||
*
|
||||
* The HLOS client writes to the send_buf, where QSAPP writes to the rcv_buf.
|
||||
* This is a blocking call.
|
||||
*
|
||||
* @param[in] handle The device handle
|
||||
* @param[in] send_buf The buffer to be sent.
|
||||
* If using ion_sbuffer, ensure this
|
||||
* QSEECOM_BUFFER_ALIGN'ed.
|
||||
* @param[in] sbuf_len The send buffer length
|
||||
* If using ion_sbuffer, ensure length is
|
||||
* multiple of QSEECOM_BUFFER_ALIGN.
|
||||
* @param[in] rcv_buf The QSEOS returned buffer.
|
||||
* If using ion_sbuffer, ensure this is
|
||||
* QSEECOM_BUFFER_ALIGN'ed.
|
||||
* @param[in] rbuf_len The returned buffer length.
|
||||
* If using ion_sbuffer, ensure length is
|
||||
* multiple of QSEECOM_BUFFER_ALIGN.
|
||||
* @param[in] QSEECom_ion_fd_info data related to memory allocated by ion.
|
||||
*
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_send_modified_cmd(struct QSEECom_handle *handle, void *send_buf,
|
||||
uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len,
|
||||
struct QSEECom_ion_fd_info *ifd_data);
|
||||
|
||||
/**
|
||||
* @brief Receive a service defined buffer.
|
||||
*
|
||||
* @param[in] handle The device handle
|
||||
* @param[out] buf The buffer that is received
|
||||
* @param[in] len The receive buffer length
|
||||
*
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_receive_req(struct QSEECom_handle *handle,
|
||||
void *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Send a response based on the previous QSEECom_receive_req.
|
||||
*
|
||||
* This allows a listener service to receive a command (e.g. read file abc).
|
||||
* The service can then handle the request from QSEECom_receive_req, and provide
|
||||
* that information back to QSAPP.
|
||||
*
|
||||
* This allows the HLOS to act as the server and QSAPP to behave as the client.
|
||||
*
|
||||
* @param[in] handle The device handle
|
||||
* @param[out] send_buf The buffer to be returned back to QSAPP
|
||||
* @param[in] len The send buffer length
|
||||
*
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_send_resp(struct QSEECom_handle *handle,
|
||||
void *send_buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Set the bandwidth for QSEE.
|
||||
*
|
||||
* This API resulst in improving the performance on the Crypto hardware
|
||||
* in QSEE. It should be called before issuing send_cmd/send_modified_cmd
|
||||
* for commands that requires using the crypto hardware on the QSEE.
|
||||
* Typically this API should be called before issuing the send request to
|
||||
* enable high performance mode and after completion of the send_cmd to
|
||||
* resume to low performance and hence to low power mode.
|
||||
*
|
||||
* This allows the clients of QSEECom to set the QSEE cyptpo HW bus
|
||||
* bandwidth to high/low.
|
||||
*
|
||||
* @param[in] high Set to 1 to enable bandwidth.
|
||||
*
|
||||
* @return Zero on success, negative on failure. errno will be set on
|
||||
* error.
|
||||
*/
|
||||
int QSEECom_set_bandwidth(struct QSEECom_handle *handle, bool high);
|
||||
|
||||
/**
|
||||
* @brief Query QSEE to check if app is loaded.
|
||||
*
|
||||
* This API queries QSEE to see if the app is loaded or not.
|
||||
*
|
||||
* @param[in] app_name Name of the app.
|
||||
*
|
||||
* @return QSEECOM_APP_QUERY_FAILED/QSEECOM_APP_NOT_LOADED/QSEECOM_APP_LOADED.
|
||||
*/
|
||||
int QSEECom_app_load_query(struct QSEECom_handle *handle, char *app_name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
|
@ -21,71 +21,288 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <endian.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <malloc.h>
|
||||
#include <signal.h>
|
||||
#include <sqlite3.h>
|
||||
#include <string.h>
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/sockets.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/fingerprint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/fingerprint.h>
|
||||
|
||||
#include "fp_klte.h"
|
||||
#include "fingerprint_tz.h"
|
||||
#include "hash.h"
|
||||
|
||||
#define MAX_COMM_CHARS 128
|
||||
#define MAX_NUM_FINGERS 5
|
||||
#define SOCKET_NAME_SEND "validityservice"
|
||||
#define SOCKET_NAME_RECEIVE "validityservice_callback"
|
||||
typedef struct vcs_fingerprint_device_t {
|
||||
fingerprint_device_t device; // "inheritance"
|
||||
uint64_t op_id;
|
||||
uint64_t challenge;
|
||||
uint64_t user_id;
|
||||
uint64_t group_id;
|
||||
uint64_t secure_user_id;
|
||||
uint64_t authenticator_id;
|
||||
uint32_t active_gid;
|
||||
sqlite3 *db;
|
||||
pthread_mutex_t lock;
|
||||
} vcs_fingerprint_device_t;
|
||||
|
||||
/******************************************************************************/
|
||||
static void checkinit(vcs_fingerprint_device_t* vdev) { //wait for hal connect validity service
|
||||
while(!vdev->init)
|
||||
sleep(1);
|
||||
}
|
||||
extern trust_zone_t tz;
|
||||
vcs_sensor_t sensor;
|
||||
|
||||
static int sendcommand(vcs_fingerprint_device_t* vdev, uint8_t* command, int num) {
|
||||
int ret = -1;
|
||||
char answer[255];
|
||||
if (fd_write(vdev->send_fd, command, num) != num) {
|
||||
ALOGE("cannot send command to service");
|
||||
//close(vdev->send_fd);
|
||||
return ret;
|
||||
}
|
||||
if (fd_read(vdev->send_fd, answer, 255))
|
||||
ret = atoi(answer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int getfingermask(vcs_fingerprint_device_t* vdev) {
|
||||
uint8_t command_getlist[2] = {CALL_GET_ENROLLED_FINGER_LIST, (uint8_t)vdev->active_gid};
|
||||
return sendcommand(vdev, command_getlist, 2);
|
||||
}
|
||||
|
||||
static int initService(vcs_fingerprint_device_t* vdev) {
|
||||
/***************************************Sensor***************************************/
|
||||
int sensor_uninit() {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
int ret = -EINVAL;
|
||||
while (vdev->send_fd <= 0) {
|
||||
vdev->send_fd = socket_local_client(SOCKET_NAME_SEND, ANDROID_SOCKET_NAMESPACE_ABSTRACT,SOCK_STREAM);
|
||||
if (vdev->send_fd < 0) {
|
||||
ALOGW("cannot open validity service!");
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
uint8_t command[1] = {CALL_INITSERVICE};
|
||||
|
||||
ret = sendcommand(vdev, command, 1);
|
||||
vdev->authenticator_id = getfingermask(vdev);
|
||||
vdev->init = true;
|
||||
int ret = 0;
|
||||
if (!sensor.init)
|
||||
return ret;
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_RESET_SPI_CONFIGURATION);
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_DISABLE_SPI_CLOCK);
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_DEVICE_SUSPEND);
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_POWER_OFF);
|
||||
sensor.init = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void send_error_notice(vcs_fingerprint_device_t* vdev, fingerprint_error_t error_info) {
|
||||
int sensor_init() {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
int ret = 0;
|
||||
int clock = 0;
|
||||
if (sensor.init)
|
||||
return ret;
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_POWER_ON);
|
||||
clock = 65535;
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_SET_CLK, &clock);
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_DEVICE_RESET);
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_SET_SPI_CONFIGURATION);
|
||||
clock = 4800;
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_SET_CLK, &clock);
|
||||
sensor.init = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sensor_process_signal(int signum) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
ALOGV("%s: signal %d received", __FUNCTION__, signum);
|
||||
int flag = 0;
|
||||
if (tz.timeout.timeout_thread) {
|
||||
pthread_mutex_lock(&tz.timeout.lock);
|
||||
pthread_cond_signal(&tz.timeout.cond);
|
||||
pthread_mutex_unlock(&tz.timeout.lock);
|
||||
//pthread_join(tz.timeout.timeout_thread, NULL);
|
||||
tz.timeout.timeout_thread = 0;
|
||||
}
|
||||
pthread_mutex_lock(&sensor.lock);
|
||||
if (get_tz_state() != STATE_IDLE && get_tz_state() != STATE_CANCEL)
|
||||
sensor.signal = true;
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_SET_DRDY_INT, &flag);
|
||||
pthread_cond_signal(&sensor.cond);
|
||||
pthread_mutex_unlock(&sensor.lock);
|
||||
}
|
||||
|
||||
int sensor_register() {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
struct vfsspi_iocRegSignal usrSignal;
|
||||
int ret = 0;
|
||||
struct sigaction sa_usr;
|
||||
sa_usr.sa_flags = 0;
|
||||
sa_usr.sa_handler = sensor_process_signal;
|
||||
sigaction(SIGUSR2, &sa_usr, NULL);
|
||||
usrSignal.userPID = getpid();
|
||||
usrSignal.signalID = SIGUSR2;
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_REGISTER_DRDY_SIGNAL, &usrSignal);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sensor_capture_start() {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
int ret = 0;
|
||||
int flag = 1;
|
||||
ret = ioctl(sensor.fd, VFSSPI_IOCTL_SET_DRDY_INT, &flag);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************Database***************************************/
|
||||
int db_check_and_create_table(void* device) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
char* errmsg;
|
||||
int ret = 0;
|
||||
char cmd[MAX_DATABASE_CMD];
|
||||
sprintf(cmd, "create table gid_%d(id integer, data blob, payload blob)", vdev->active_gid);
|
||||
ret = sqlite3_exec(vdev->db, cmd, NULL, NULL, &errmsg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int db_convert_old_db(vcs_fingerprint_device_t* vdev) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
int ret = 0;
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *stat;
|
||||
char cmd[MAX_DATABASE_CMD];
|
||||
int idx = 0;
|
||||
|
||||
memset(tz.finger, 0, MAX_NUM_FINGERS * sizeof(finger_t));
|
||||
ret = sqlite3_open(SAMSUNG_FP_DB_PATH, &db);
|
||||
if (ret != SQLITE_OK) {
|
||||
ALOGE("Open samsung finger database failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(cmd, "select * from enrollments");
|
||||
sqlite3_prepare(db, cmd, -1, &stat, 0);
|
||||
while(1) {
|
||||
int ret = sqlite3_step(stat);
|
||||
if (ret != SQLITE_ROW) {
|
||||
break;
|
||||
}
|
||||
int id = sqlite3_column_int(stat, 1);
|
||||
const void *data = sqlite3_column_blob(stat, 2);
|
||||
int len = sqlite3_column_bytes(stat, 2);
|
||||
memcpy(tz.finger[id].data, data, len);
|
||||
ALOGV("read fingerprint data from samsung fp database: id=%d", id);
|
||||
tz.finger[id].exist = true;
|
||||
}
|
||||
sqlite3_finalize(stat);
|
||||
|
||||
memset(cmd, 0, MAX_DATABASE_CMD);
|
||||
sprintf(cmd, "select * from properties");
|
||||
sqlite3_prepare(db, cmd, -1, &stat, 0);
|
||||
sqlite3_step(stat);
|
||||
const void *payload = sqlite3_column_blob(stat, 2);
|
||||
int len = sqlite3_column_bytes(stat, 2);
|
||||
for (idx = 1; idx <= MAX_NUM_FINGERS; idx++) {
|
||||
if (tz.finger[idx].exist) {
|
||||
memcpy(tz.finger[idx].payload, payload, len);
|
||||
db_write_to_db(vdev, false, idx);
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(stat);
|
||||
|
||||
ret = sqlite3_close(db);
|
||||
if (ret != SQLITE_OK) {
|
||||
ALOGE("Close samsung finger database failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = remove(SAMSUNG_FP_DB_PATH);
|
||||
if (ret) {
|
||||
ALOGE("Cannot remove Samsung fingerprint database");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int db_read_to_tz(void* device) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
char* errmsg;
|
||||
int ret = 0;
|
||||
char cmd[MAX_DATABASE_CMD];
|
||||
sqlite3_stmt *stat;
|
||||
|
||||
db_check_and_create_table(vdev);
|
||||
|
||||
if (!access(SAMSUNG_FP_DB_PATH, 0)) {
|
||||
ALOGI("Samsung fingerprint database exist! Convert it");
|
||||
return db_convert_old_db(vdev);
|
||||
}
|
||||
|
||||
memset(tz.finger, 0, MAX_NUM_FINGERS * sizeof(finger_t));
|
||||
sprintf(cmd, "select * from gid_%d", vdev->active_gid);
|
||||
sqlite3_prepare(vdev->db, cmd, -1, &stat, 0);
|
||||
while(1) {
|
||||
int ret = sqlite3_step(stat);
|
||||
if (ret != SQLITE_ROW) {
|
||||
break;
|
||||
}
|
||||
int id = sqlite3_column_int(stat, 0);
|
||||
const void *data = sqlite3_column_blob(stat, 1);
|
||||
memcpy(tz.finger[id].data, data, FINGER_DATA_MAX_LENGTH);
|
||||
const void *payload = sqlite3_column_blob(stat, 2);
|
||||
memcpy(tz.finger[id].payload, payload, PAYLOAD_MAX_LENGTH);
|
||||
ALOGV("read fingerprint data from database: id=%d", id);
|
||||
tz.finger[id].exist = true;
|
||||
}
|
||||
sqlite3_finalize(stat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int db_write_to_db(void* device, bool remove, int fid) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
char* errmsg;
|
||||
int ret = 0;
|
||||
char cmd[MAX_DATABASE_CMD];
|
||||
sqlite3_stmt *stat;
|
||||
if (remove) {
|
||||
sprintf(cmd, "delete from gid_%d where id=%d", vdev->active_gid, fid);
|
||||
ret = sqlite3_exec(vdev->db, cmd, NULL, NULL, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
ALOGE("Remove finger from database failed!");
|
||||
}
|
||||
memset(&tz.finger[fid], 0, sizeof(finger_t));
|
||||
} else {
|
||||
sprintf(cmd, "insert into gid_%d(id, data, payload) values( %d, ?, ?)", vdev->active_gid, fid);
|
||||
sqlite3_prepare(vdev->db, cmd, -1, &stat, 0);
|
||||
sqlite3_bind_blob(stat, 1, tz.finger[fid].data, (int)FINGER_DATA_MAX_LENGTH, NULL);
|
||||
sqlite3_bind_blob(stat, 2, tz.finger[fid].payload, (int)PAYLOAD_MAX_LENGTH, NULL);
|
||||
ret = sqlite3_step(stat);
|
||||
sqlite3_finalize(stat);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int db_init(void* device) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
int ret = 0;
|
||||
ret = sqlite3_open(FINGER_DATABASE_FILENAME, &vdev->db);
|
||||
if (ret != SQLITE_OK) {
|
||||
ALOGE("Open finger database failed!");
|
||||
return -1;
|
||||
}
|
||||
return db_read_to_tz(vdev);
|
||||
}
|
||||
|
||||
int db_uninit(void* device) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
int ret = 0;
|
||||
ret = sqlite3_close(vdev->db);
|
||||
if (ret != SQLITE_OK) {
|
||||
ALOGE("Close finger database failed!");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************notice***************************************/
|
||||
fingerprint_acquired_info_t convert_ret_to_acquired_info(int acquired_ret) { //TODO
|
||||
ALOGV("----------------> %s ----------------->acquired_ret=%d", __FUNCTION__, acquired_ret);
|
||||
fingerprint_acquired_info_t ret = FINGERPRINT_ACQUIRED_GOOD;
|
||||
switch (acquired_ret) {
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
ret = FINGERPRINT_ACQUIRED_INSUFFICIENT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void send_error_notice(void* device, int error_info_int) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
fingerprint_error_t error_info = (fingerprint_error_t)error_info_int;
|
||||
|
||||
fingerprint_msg_t msg = {0};
|
||||
msg.type = FINGERPRINT_ERROR;
|
||||
msg.data.error = error_info;
|
||||
ALOGI("error_info=%d", (int)error_info);
|
||||
ALOGV("recevied error notice! error_info=%d", (int)error_info);
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
vdev->device.notify(&msg);
|
||||
|
@ -94,8 +311,10 @@ static void send_error_notice(vcs_fingerprint_device_t* vdev, fingerprint_error_
|
|||
return;
|
||||
}
|
||||
|
||||
static void send_acquired_notice(vcs_fingerprint_device_t* vdev, fingerprint_acquired_info_t acquired_info) {
|
||||
void send_acquired_notice(void* device, int acquired_ret) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
fingerprint_acquired_info_t acquired_info = convert_ret_to_acquired_info(acquired_ret);
|
||||
|
||||
fingerprint_msg_t acqu_msg = {0};
|
||||
acqu_msg.type = FINGERPRINT_ACQUIRED;
|
||||
|
@ -109,22 +328,21 @@ static void send_acquired_notice(vcs_fingerprint_device_t* vdev, fingerprint_acq
|
|||
return;
|
||||
}
|
||||
|
||||
static void send_enroll_notice(vcs_fingerprint_device_t* vdev, int fid, int remaining) {
|
||||
void send_enroll_notice(void* device, int fid, int remaining) {
|
||||
ALOGV("----------------> %s -----------------> fid %d", __FUNCTION__, fid);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
|
||||
if (fid == 0) {
|
||||
ALOGD("Fingerprint ID is zero (invalid)");
|
||||
ALOGE("Fingerprint ID is zero (invalid)");
|
||||
return;
|
||||
}
|
||||
if (vdev->secure_user_id == 0) {
|
||||
ALOGD("Secure user ID is zero (invalid)");
|
||||
ALOGE("Secure user ID is zero (invalid)");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
|
||||
vdev->listener.state = STATE_SCAN;
|
||||
|
||||
fingerprint_msg_t msg = {0};
|
||||
msg.type = FINGERPRINT_TEMPLATE_ENROLLING;
|
||||
msg.data.enroll.finger.fid = fid;
|
||||
|
@ -136,8 +354,9 @@ static void send_enroll_notice(vcs_fingerprint_device_t* vdev, int fid, int rema
|
|||
return;
|
||||
}
|
||||
|
||||
static void send_authenticated_notice(vcs_fingerprint_device_t* vdev, int fid) {
|
||||
void send_authenticated_notice(void* device, int fid) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
|
||||
send_acquired_notice(vdev, FINGERPRINT_ACQUIRED_GOOD);
|
||||
|
||||
|
@ -163,8 +382,9 @@ static void send_authenticated_notice(vcs_fingerprint_device_t* vdev, int fid) {
|
|||
return;
|
||||
}
|
||||
|
||||
static void send_remove_notice(vcs_fingerprint_device_t* vdev, int fid) {
|
||||
void send_remove_notice(void* device, int fid) {
|
||||
ALOGV("----------------> %s ----------------->fid=%d", __FUNCTION__, fid);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
|
||||
fingerprint_msg_t msg = {0};
|
||||
msg.type = FINGERPRINT_TEMPLATE_REMOVED;
|
||||
|
@ -177,20 +397,14 @@ static void send_remove_notice(vcs_fingerprint_device_t* vdev, int fid) {
|
|||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static uint64_t get_64bit_rand() {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
uint64_t r = (((uint64_t)rand()) << 32) | ((uint64_t)rand());
|
||||
return r != 0 ? r : 1;
|
||||
}
|
||||
/***************************************HAL function***************************************/
|
||||
|
||||
static uint64_t fingerprint_get_auth_id(struct fingerprint_device* device) {
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
uint64_t authenticator_id = 0;
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
vdev->authenticator_id = getfingermask(vdev);
|
||||
vdev->authenticator_id = hash_file(FINGER_DATABASE_FILENAME);
|
||||
authenticator_id = vdev->authenticator_id;
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
|
@ -199,9 +413,11 @@ static uint64_t fingerprint_get_auth_id(struct fingerprint_device* device) {
|
|||
|
||||
static int fingerprint_set_active_group(struct fingerprint_device *device, uint32_t gid,
|
||||
const char __unused *path) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
vdev->active_gid = gid;
|
||||
db_read_to_tz(vdev);
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
return 0;
|
||||
|
@ -215,33 +431,24 @@ static int fingerprint_authenticate(struct fingerprint_device *device,
|
|||
int ret = 0;
|
||||
ALOGI("auth: op_id=%llu ",operation_id);
|
||||
|
||||
checkinit(vdev);
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
|
||||
vdev->op_id = operation_id;
|
||||
vdev->listener.state = STATE_SCAN;
|
||||
uint8_t command[2] = {CALL_IDENTIFY, (uint8_t)vdev->active_gid};
|
||||
ret = sendcommand(vdev, command, 2);
|
||||
ret = vcs_start_authenticate(vdev);
|
||||
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
// Always return successful
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fingerprint_enroll(struct fingerprint_device *device,
|
||||
const hw_auth_token_t *hat,
|
||||
uint32_t __unused gid,
|
||||
uint32_t __unused timeout_sec) {
|
||||
ALOGD("fingerprint_enroll");
|
||||
uint32_t timeout_sec) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
int ret = -EINVAL;
|
||||
int fingermask = 0;
|
||||
int idx = 1;
|
||||
uint8_t command[3] = {CALL_ENROLL, (uint8_t)vdev->active_gid, 0};
|
||||
|
||||
checkinit(vdev);
|
||||
|
||||
if (!hat) {
|
||||
ALOGW("%s: null auth token", __func__);
|
||||
|
@ -263,26 +470,21 @@ static int fingerprint_enroll(struct fingerprint_device *device,
|
|||
vdev->user_id = hat->user_id;
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
vdev->listener.state = STATE_ENROLL;
|
||||
|
||||
fingermask = getfingermask(vdev);
|
||||
ALOGI("fingerprint_enroll: fingermask=%d", fingermask);
|
||||
for (idx = 1; idx <= MAX_NUM_FINGERS; idx++)
|
||||
if (!((fingermask >> idx) & 1))
|
||||
for (idx = 1; idx <= MAX_NUM_FINGERS; idx++) {
|
||||
if (!tz.finger[idx].exist) {
|
||||
break;
|
||||
|
||||
command[2] = (uint8_t)idx;
|
||||
ret = sendcommand(vdev, command, 3);
|
||||
}
|
||||
}
|
||||
if (idx > MAX_NUM_FINGERS) {
|
||||
send_error_notice(vdev, FINGERPRINT_ERROR_NO_SPACE);
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
return -1;
|
||||
}
|
||||
ret = vcs_start_enroll(vdev, timeout_sec);
|
||||
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
ALOGI("enroll ret=%d",ret);
|
||||
|
||||
// workaround
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
vdev->authenticator_id = getfingermask(vdev);
|
||||
ALOGV("enroll ret=%d",ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -292,7 +494,7 @@ static uint64_t fingerprint_pre_enroll(struct fingerprint_device *device) {
|
|||
uint64_t challenge = 0;
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
|
||||
challenge = get_64bit_rand();
|
||||
challenge = hash_string(tz.auth_token);
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
vdev->challenge = challenge;
|
||||
|
@ -316,15 +518,27 @@ static int fingerprint_cancel(struct fingerprint_device *device) {
|
|||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
int ret = 0;
|
||||
int flag = 0;
|
||||
|
||||
checkinit(vdev);
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
vdev->listener.state = STATE_IDLE;
|
||||
|
||||
uint8_t command[1] = {CALL_CANCEL};
|
||||
ret = sendcommand(vdev, command, 1);
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
if (tz.timeout.timeout_thread) {
|
||||
pthread_mutex_lock(&tz.timeout.lock);
|
||||
pthread_cond_signal(&tz.timeout.cond);
|
||||
pthread_mutex_unlock(&tz.timeout.lock);
|
||||
pthread_join(tz.timeout.timeout_thread, NULL);
|
||||
tz.timeout.timeout_thread = 0;
|
||||
}
|
||||
if (get_tz_state() != STATE_IDLE && get_tz_state() != STATE_CANCEL) {
|
||||
set_tz_state(STATE_CANCEL);
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_SET_DRDY_INT, &flag);
|
||||
pthread_mutex_lock(&sensor.lock);
|
||||
pthread_cond_signal(&sensor.cond);
|
||||
pthread_mutex_unlock(&sensor.lock);
|
||||
while (1) {
|
||||
usleep(100000);
|
||||
if (tz.state == STATE_IDLE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -337,17 +551,12 @@ static int fingerprint_enumerate(struct fingerprint_device *device,
|
|||
return -1;
|
||||
}
|
||||
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
int num = 0;
|
||||
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
|
||||
int fingermask = getfingermask(vdev);
|
||||
|
||||
ALOGI("fingerprint_enumerate: fingermask=%d", fingermask);
|
||||
int idx = 0;
|
||||
for (idx = 0; idx < MAX_NUM_FINGERS; idx++)
|
||||
if ((fingermask >> (idx + 1)) & 1)
|
||||
num++;
|
||||
num = vcs_get_enrolled_finger_num();
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
return num;
|
||||
|
@ -355,7 +564,7 @@ static int fingerprint_enumerate(struct fingerprint_device *device,
|
|||
|
||||
static int fingerprint_remove(struct fingerprint_device *device,
|
||||
uint32_t __unused gid, uint32_t fid) {
|
||||
int idx = 0, ret = 0;
|
||||
int ret = 0;
|
||||
ALOGV("----------------> %s -----------------> fid %d", __FUNCTION__, fid);
|
||||
if (device == NULL) {
|
||||
ALOGE("Can't remove fingerprint (gid=%d, fid=%d); "
|
||||
|
@ -366,50 +575,31 @@ static int fingerprint_remove(struct fingerprint_device *device,
|
|||
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
|
||||
uint8_t command[3] = {CALL_REMOVE, (uint8_t)vdev->active_gid, 0};
|
||||
|
||||
checkinit(vdev);
|
||||
|
||||
if (fid == 0) {
|
||||
// Delete all fingerprints
|
||||
command[2] = 21;
|
||||
int fingermask = getfingermask(vdev);
|
||||
int idx = 1;
|
||||
for (idx = 1; idx <= MAX_NUM_FINGERS; idx++)
|
||||
if (tz.finger[idx].exist) {
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
ret = sendcommand(vdev, command, 3);
|
||||
ret = db_write_to_db(vdev, true, idx);
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
if (ret == 0) {
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
int idx = 0;
|
||||
for (idx = 0; idx < MAX_NUM_FINGERS; idx++)
|
||||
if ((fingermask >> (idx + 1)) & 1) {
|
||||
send_remove_notice(vdev, idx + 1);
|
||||
send_remove_notice(vdev, idx);
|
||||
}
|
||||
}
|
||||
} // end if
|
||||
vdev->listener.state = STATE_IDLE;
|
||||
} else {
|
||||
// Delete one fingerprint
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
|
||||
command[2] = (uint8_t)fid;
|
||||
ret = sendcommand(vdev, command, 3);
|
||||
vdev->listener.state = STATE_IDLE;
|
||||
ret = db_write_to_db(vdev, true, fid);
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
// Always send remove notice
|
||||
if (ret == 0) {
|
||||
send_remove_notice(vdev, fid);
|
||||
}
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
|
||||
int fingermask = getfingermask(vdev);
|
||||
if (fingermask == 0) { // All finger are removed
|
||||
command[2] = 21;
|
||||
sendcommand(vdev, command, 3);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
if (ret) {
|
||||
ALOGE("Can't remove finger %d", fid);
|
||||
send_error_notice(vdev, FINGERPRINT_ERROR_UNABLE_TO_REMOVE);
|
||||
}
|
||||
|
||||
|
@ -427,7 +617,6 @@ static int set_notify_callback(struct fingerprint_device *device,
|
|||
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
vdev->listener.state = STATE_IDLE;
|
||||
device->notify = notify;
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
ALOGD("fingerprint callback notification set");
|
||||
|
@ -435,78 +624,6 @@ static int set_notify_callback(struct fingerprint_device *device,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static worker_state_t getListenerState(vcs_fingerprint_device_t* dev) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
worker_state_t state = STATE_IDLE;
|
||||
|
||||
pthread_mutex_lock(&dev->lock);
|
||||
state = dev->listener.state;
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static void* listenerSocket(void* data) {
|
||||
ALOGI("----------------> %s ----------------->", __FUNCTION__);
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)data;
|
||||
|
||||
while (vdev->receive_fd <= 0) {
|
||||
vdev->receive_fd = socket_local_client(SOCKET_NAME_RECEIVE, ANDROID_SOCKET_NAMESPACE_ABSTRACT,SOCK_STREAM);
|
||||
if (vdev->receive_fd < 0) {
|
||||
ALOGW("listener cannot open fingerprint listener service");
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
initService(vdev);
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
vdev->listener.state = STATE_IDLE;
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
while (1) {
|
||||
int size = 0;
|
||||
char buffer[MAX_COMM_CHARS] = {0};
|
||||
if (getListenerState(vdev) == STATE_EXIT) {
|
||||
ALOGD("Received request to exit listener thread");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((size = fd_read(vdev->receive_fd, buffer,
|
||||
sizeof(buffer) - 1)) > 0) {
|
||||
buffer[size] = '\0';
|
||||
int type, info, info_ex;
|
||||
sscanf(buffer, "%d:%d:%d", &type, &info, &info_ex);
|
||||
switch (type) {
|
||||
case 1: //error
|
||||
send_error_notice(vdev, info);
|
||||
break;
|
||||
case 2: //enroll
|
||||
send_enroll_notice(vdev, info, info_ex);
|
||||
break;
|
||||
case 3: //removed
|
||||
send_remove_notice(vdev, info);
|
||||
break;
|
||||
case 4: //acquired
|
||||
send_acquired_notice(vdev, info);
|
||||
break;
|
||||
case 5: //authenticated
|
||||
send_authenticated_notice(vdev, info);
|
||||
break;
|
||||
default:
|
||||
ALOGE("unknow type:%d", type);
|
||||
}
|
||||
} else {
|
||||
ALOGE("fingerprint listener receive failure");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
ALOGD("Listener exit !!");
|
||||
done_quiet:
|
||||
close(vdev->receive_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int fingerprint_close(hw_device_t* device) {
|
||||
ALOGV("----------------> %s ----------------->", __FUNCTION__);
|
||||
if (device == NULL) {
|
||||
|
@ -516,18 +633,18 @@ static int fingerprint_close(hw_device_t* device) {
|
|||
|
||||
vcs_fingerprint_device_t* vdev = (vcs_fingerprint_device_t*)device;
|
||||
|
||||
checkinit(vdev);
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
// Ask listener thread to exit
|
||||
vdev->listener.state = STATE_EXIT;
|
||||
uint8_t command[1] = {CALL_CLEANUP};
|
||||
sendcommand(vdev, command, 1);
|
||||
db_uninit(vdev);
|
||||
vcs_init();
|
||||
vcs_stop_auth_session();
|
||||
vcs_uninit();
|
||||
sensor_uninit();
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
pthread_join(vdev->listener.thread, NULL);
|
||||
pthread_mutex_destroy(&vdev->lock);
|
||||
close(vdev->send_fd);
|
||||
pthread_mutex_destroy(&sensor.lock);
|
||||
pthread_mutex_destroy(&tz.lock);
|
||||
pthread_mutex_destroy(&tz.timeout.lock);
|
||||
free(vdev);
|
||||
|
||||
return 0;
|
||||
|
@ -568,15 +685,39 @@ static int fingerprint_open(const hw_module_t* module, const char __unused *id,
|
|||
vdev->device.notify = NULL;
|
||||
|
||||
vdev->active_gid = 0;
|
||||
vdev->init = false;
|
||||
memset(&tz, 0, sizeof(trust_zone_t));
|
||||
|
||||
pthread_mutex_init(&vdev->lock, NULL);
|
||||
if (pthread_create(&vdev->listener.thread, NULL, listenerSocket, vdev) !=
|
||||
0)
|
||||
return -1;
|
||||
pthread_mutex_init(&sensor.lock, NULL);
|
||||
pthread_mutex_init(&tz.lock, NULL);
|
||||
pthread_mutex_init(&tz.timeout.lock, NULL);
|
||||
pthread_cond_init(&tz.timeout.cond, NULL);
|
||||
pthread_cond_init(&sensor.cond, NULL);
|
||||
tz.timeout.timeout_thread = 0;
|
||||
|
||||
*device = &vdev->device.common;
|
||||
|
||||
memset(&sensor, 0, sizeof(vcs_sensor_t));
|
||||
sensor.fd = open(SENSOR_FILE_NAME, O_RDWR);
|
||||
if (sensor.fd < 0) {
|
||||
ALOGE("Open sensor error!");
|
||||
return -1;
|
||||
}
|
||||
sensor_init();
|
||||
sensor_register();
|
||||
sensor_uninit();
|
||||
|
||||
pthread_mutex_lock(&vdev->lock);
|
||||
sensor_init();
|
||||
db_init(vdev);
|
||||
vcs_init();
|
||||
vcs_uninit();
|
||||
vcs_init();
|
||||
vcs_start_auth_session();
|
||||
vcs_uninit();
|
||||
sensor_uninit();
|
||||
pthread_mutex_unlock(&vdev->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
77
fingerprint/fingerprint_common.h
Normal file
77
fingerprint/fingerprint_common.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||
* may not use this file except in compliance with the License. You may
|
||||
* obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __FINGERPRINT_COMMON_H_
|
||||
#define __FINGERPRINT_COMMON_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SB_LENGTH (0x100000)
|
||||
#define BUFFER_LENGTH (0x19000)
|
||||
#define AUTH_TOKEN_LENGTH (0x70)
|
||||
#define AUTH_SESSION_TOKEN_LENGTH (0x20)
|
||||
#define CALIBRATE_DATA_MAX_LENGTH (0x500c)
|
||||
#define FINGER_DATA_MAX_LENGTH (0x2900)
|
||||
#define PAYLOAD_MAX_LENGTH (0x24)
|
||||
#define MAX_NUM_FINGERS (5)
|
||||
|
||||
typedef enum worker_state_t {
|
||||
STATE_IDLE = 0,
|
||||
STATE_ENROLL,
|
||||
STATE_SCAN,
|
||||
STATE_CANCEL
|
||||
} worker_state_t;
|
||||
|
||||
typedef struct vcs_sensor_t {
|
||||
int fd;
|
||||
bool init;
|
||||
bool signal;
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t lock;
|
||||
}vcs_sensor_t;
|
||||
|
||||
typedef struct finger_t {
|
||||
bool exist;
|
||||
char data[FINGER_DATA_MAX_LENGTH];
|
||||
char payload[PAYLOAD_MAX_LENGTH];
|
||||
}finger_t;
|
||||
|
||||
typedef struct timeout_t {
|
||||
uint32_t timeout;
|
||||
pthread_t timeout_thread;
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t lock;
|
||||
}timeout_t;
|
||||
|
||||
typedef struct trust_zone_t {
|
||||
bool init;
|
||||
worker_state_t state;
|
||||
struct QSEECom_handle *qhandle;
|
||||
bool auth_session_opend;
|
||||
char auth_token[AUTH_TOKEN_LENGTH];
|
||||
char auth_session_token[AUTH_SESSION_TOKEN_LENGTH];
|
||||
int calibrate_len;
|
||||
char calibrate_data[CALIBRATE_DATA_MAX_LENGTH];
|
||||
finger_t finger[MAX_NUM_FINGERS + 1]; // Start from finger[1]
|
||||
timeout_t timeout;
|
||||
pthread_t auth_thread;
|
||||
pthread_t enroll_thread;
|
||||
pthread_mutex_t lock;
|
||||
}trust_zone_t;
|
||||
|
||||
#endif //__FINGERPRINT_COMMON_H_
|
735
fingerprint/fingerprint_tz.c
Normal file
735
fingerprint/fingerprint_tz.c
Normal file
|
@ -0,0 +1,735 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||
* may not use this file except in compliance with the License. You may
|
||||
* obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "Fingerprint_tz"
|
||||
#define LOG_NDEBUG 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "fingerprint_tz.h"
|
||||
#include "fp_klte.h"
|
||||
|
||||
extern vcs_sensor_t sensor;
|
||||
trust_zone_t tz;
|
||||
|
||||
worker_state_t get_tz_state() {
|
||||
worker_state_t state;
|
||||
|
||||
pthread_mutex_lock(&tz.lock);
|
||||
state = tz.state;
|
||||
pthread_mutex_unlock(&tz.lock);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void set_tz_state(worker_state_t state) {
|
||||
pthread_mutex_lock(&tz.lock);
|
||||
tz.state = state;
|
||||
pthread_mutex_unlock(&tz.lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: vendorUpdateCalData
|
||||
*/
|
||||
int vcs_update_cal_data() {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_vendor_cmd_t *send_vendor_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
send_vendor_cmd = (trust_zone_vendor_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_vendor_cmd_t)));
|
||||
|
||||
memset(send_vendor_cmd, 0, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_vendor_cmd->cmd = vfmVendorDefinedOperation;
|
||||
send_vendor_cmd->vendor_cmd = vendorUpdateCalData;
|
||||
resp->data[0] = CALIBRATE_DATA_MAX_LENGTH;
|
||||
ret = QSEECom_send_cmd(handle, send_vendor_cmd, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("Update Cal Data error");
|
||||
return ret;
|
||||
}
|
||||
tz.calibrate_len = resp->data[3] + 0xf;
|
||||
memcpy(&tz.calibrate_data, &resp->data[2], tz.calibrate_len);
|
||||
ALOGV("Sended vendorUpdateCalData");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vcs_check_state() {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_base_cmd_t *send_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
send_cmd = (trust_zone_base_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(int)));
|
||||
|
||||
if (get_tz_state() == STATE_IDLE)
|
||||
return 1;
|
||||
if (get_tz_state() == STATE_CANCEL) {
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(int)) + QSEECOM_ALIGN(sizeof(int)));
|
||||
send_cmd->cmd = vfmCaptureAbort;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(int)), resp, QSEECOM_ALIGN(sizeof(int)));
|
||||
set_tz_state(STATE_IDLE);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: 1.vfmCaptureStart
|
||||
* 2.vfmCaptureReadData * N
|
||||
* 3.vfmCaptureProcessData
|
||||
*/
|
||||
int vcs_start_capture(void *vdev, time_t t) {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_base_cmd_t *send_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
send_cmd = (trust_zone_base_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_base_cmd_t)));
|
||||
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(*send_cmd)) + QSEECOM_ALIGN(sizeof(int)));
|
||||
send_cmd->cmd = vfmCaptureStart;
|
||||
send_cmd->len = 0x1c;
|
||||
send_cmd->data[16] = 0x1;
|
||||
if (t) {
|
||||
*(time_t*)(&send_cmd->data[20]) = t;
|
||||
}
|
||||
send_cmd->data[24] = 0xc0;
|
||||
send_cmd->data[25] = 0x12;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(int)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("Send vfmCaptureStart error");
|
||||
return ret;
|
||||
}
|
||||
vcs_update_cal_data();
|
||||
pthread_mutex_lock(&sensor.lock);
|
||||
sensor_capture_start();
|
||||
pthread_mutex_unlock(&sensor.lock);
|
||||
|
||||
pthread_mutex_lock(&sensor.lock);
|
||||
while ((!vcs_check_state()) && !sensor.signal) {
|
||||
pthread_cond_wait(&sensor.cond, &sensor.lock);
|
||||
}
|
||||
pthread_mutex_unlock(&sensor.lock);
|
||||
if (vcs_check_state()) {
|
||||
return -1;
|
||||
}
|
||||
pthread_mutex_lock(&sensor.lock);
|
||||
if (sensor.signal == true) {
|
||||
sensor.signal = false;
|
||||
}
|
||||
pthread_mutex_unlock(&sensor.lock);
|
||||
|
||||
while(1) {
|
||||
if (vcs_check_state()) {
|
||||
return -1;
|
||||
}
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(int)));
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(int)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_cmd->cmd = vfmCaptureReadData;
|
||||
send_cmd->len = 0x8000;
|
||||
resp->data[0] = 0xc;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(int)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("Send vfmCaptureReadData error");
|
||||
continue;
|
||||
}
|
||||
if (resp->data[2] == 2) {
|
||||
ALOGV("User's finger removed from sensor");
|
||||
break;
|
||||
}
|
||||
//usleep(200000);
|
||||
}
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_base_cmd_t)));
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(*send_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_cmd->cmd = vfmCaptureProcessData;
|
||||
send_cmd->len = 0x1c;
|
||||
send_cmd->data[16] = 0x1;
|
||||
*(time_t*)(&send_cmd->data[20]) = time(NULL);
|
||||
send_cmd->data[24] = 0xc0;
|
||||
send_cmd->data[25] = 0x12;
|
||||
resp->data[0] = 0xc;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(int)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret) {
|
||||
ALOGE("Send vfmCaptureProcessData error");
|
||||
return -1;
|
||||
}
|
||||
if (resp->result != 0) {
|
||||
ALOGE("resp->result=%d",resp->result);
|
||||
send_acquired_notice(vdev, resp->result);
|
||||
return vcs_start_capture(vdev, time(NULL));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: 1.vendorUnknown0
|
||||
* 2.vcs_start_capture
|
||||
* 3.vfmMatchImageToTemplates
|
||||
* 4.vfmPayloadRelease
|
||||
*/
|
||||
|
||||
void* vcs_authenticate(void* vdev) {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_vendor_cmd_t *send_vendor_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
send_vendor_cmd = (trust_zone_vendor_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_vendor_cmd_t)));
|
||||
int fingerindex = 0;
|
||||
int len = 0;
|
||||
int fake_fid = 0;
|
||||
|
||||
memset(send_vendor_cmd, 0, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_vendor_cmd->cmd = vfmVendorDefinedOperation;
|
||||
send_vendor_cmd->vendor_cmd = vendorUnknown0;
|
||||
resp->data[0] = 0x4;
|
||||
ret = QSEECom_send_cmd(handle, send_vendor_cmd, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (resp->result) {
|
||||
ALOGE("%s:Send vendor unknown 0 cmd error", __FUNCTION__);
|
||||
}
|
||||
while (get_tz_state() == STATE_SCAN) {
|
||||
ret = vcs_start_capture(vdev, 0);
|
||||
if (ret == -1)
|
||||
goto out;
|
||||
trust_zone_5x_cmd_t *send_5x_cmd = NULL;
|
||||
trust_zone_2x_result_t *resp_2x = NULL;
|
||||
int idx = 1;
|
||||
send_5x_cmd = (trust_zone_5x_cmd_t *)handle->ion_sbuffer;
|
||||
resp_2x = (trust_zone_2x_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_5x_cmd_t)));
|
||||
|
||||
memset(send_5x_cmd, 0, QSEECOM_ALIGN(sizeof(*send_5x_cmd)) + QSEECOM_ALIGN(sizeof(*resp_2x)));
|
||||
send_5x_cmd->cmd = vfmMatchImageToTemplates;
|
||||
send_5x_cmd->len = 0x14;
|
||||
send_5x_cmd->unknown[0] = 1;
|
||||
send_5x_cmd->unknown[1] = 100000;
|
||||
send_5x_cmd->time_now = time(NULL);
|
||||
send_5x_cmd->data[0] = 0x1;
|
||||
send_5x_cmd->data[102388] = vcs_get_enrolled_finger_num();
|
||||
len = 0;
|
||||
for (idx = 1; idx <= MAX_NUM_FINGERS; idx++)
|
||||
if (tz.finger[idx].exist) {
|
||||
len++;
|
||||
int address = 102392 + (len - 1) * 15364;
|
||||
send_5x_cmd->data[address] = 0x45;
|
||||
send_5x_cmd->data[address + 1] = 0x28;
|
||||
memcpy(&send_5x_cmd->data[address + 4], &tz.finger[idx].data, FINGER_DATA_MAX_LENGTH);
|
||||
}
|
||||
resp_2x->data[0] = 0x5c;
|
||||
resp_2x->data[25602] = 0x3000;
|
||||
ret = QSEECom_send_cmd(handle, send_5x_cmd, QSEECOM_ALIGN(sizeof(*send_5x_cmd)), resp_2x, QSEECOM_ALIGN(sizeof(*resp_2x)));
|
||||
if (ret) {
|
||||
ALOGE("%s:send vfmMatchImageToTemplates error", __FUNCTION__);
|
||||
send_error_notice(vdev, FINGERPRINT_ERROR_UNABLE_TO_PROCESS);
|
||||
goto out;
|
||||
}
|
||||
if (resp_2x->result != 0) {
|
||||
send_acquired_notice(vdev, resp_2x->result);
|
||||
continue;
|
||||
}
|
||||
fake_fid = (int)resp_2x->data[22] + 1;
|
||||
len = 0;
|
||||
for (idx = 1; idx <= MAX_NUM_FINGERS; idx++) {
|
||||
if (tz.finger[idx].exist) {
|
||||
len++;
|
||||
if (len == fake_fid) {
|
||||
fingerindex = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ALOGV("Auth fingerindex=%d", fingerindex);
|
||||
//memcpy(&tz.finger[fingerindex].data, &resp_2x->data[102419], FINGER_DATA_MAX_LENGTH);
|
||||
//db_write_to_db(vdev, false, fingerindex);
|
||||
|
||||
trust_zone_2x_cmd_t *send_2x_cmd = NULL;
|
||||
send_2x_cmd = (trust_zone_2x_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_2x_cmd_t)));
|
||||
memset(send_2x_cmd, 0, QSEECOM_ALIGN(sizeof(*send_2x_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_2x_cmd->cmd = vfmPayloadRelease;
|
||||
send_2x_cmd->len = PAYLOAD_MAX_LENGTH;
|
||||
memcpy(&send_2x_cmd->data, &tz.finger[fingerindex].payload, PAYLOAD_MAX_LENGTH);
|
||||
resp->data[0] = 0x24;
|
||||
ret = QSEECom_send_cmd(handle, send_2x_cmd, QSEECOM_ALIGN(sizeof(*send_2x_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
break;
|
||||
}
|
||||
out:
|
||||
sensor_uninit();
|
||||
vcs_uninit();
|
||||
set_tz_state(STATE_IDLE);
|
||||
if (fingerindex) {
|
||||
send_authenticated_notice(vdev, fingerindex);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: 1.vfmEnrollBegin
|
||||
* 2.vendorUnknownA
|
||||
* 3.vcs_start_capture * 8
|
||||
* 4.vfmEnrollAddImage
|
||||
* 5.vfmEnrollFinish
|
||||
* 6.vfmPayloadBind
|
||||
* 7.vfmEnrollmentPasswordSet
|
||||
*/
|
||||
|
||||
void* vcs_enroll(void* vdev) {
|
||||
int count = 8;
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_base_cmd_t *send_cmd = NULL;
|
||||
trust_zone_vendor_cmd_t *send_vendor_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
send_cmd = (trust_zone_base_cmd_t *)handle->ion_sbuffer;
|
||||
send_vendor_cmd = (trust_zone_vendor_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_base_cmd_t)));
|
||||
|
||||
int idx = 1;
|
||||
for (idx = 1; idx <= MAX_NUM_FINGERS; idx++) {
|
||||
if (!tz.finger[idx].exist) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(*send_cmd)) + QSEECOM_ALIGN(sizeof(int)));
|
||||
send_cmd->cmd = vfmEnrollBegin;
|
||||
send_cmd->data[102400] = idx;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(int)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("send EnrollBegin error");
|
||||
set_tz_state(STATE_IDLE);
|
||||
send_error_notice(vdev, FINGERPRINT_ERROR_UNABLE_TO_PROCESS);
|
||||
return NULL;
|
||||
}
|
||||
memset(send_vendor_cmd, 0, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_vendor_cmd->cmd = vfmVendorDefinedOperation;
|
||||
send_vendor_cmd->vendor_cmd = vendorUnknownA;
|
||||
resp->data[0] = 0x4;
|
||||
ret = QSEECom_send_cmd(handle, send_vendor_cmd, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("send vendorUnknownA error");
|
||||
set_tz_state(STATE_IDLE);
|
||||
send_error_notice(vdev, FINGERPRINT_ERROR_UNABLE_TO_PROCESS);
|
||||
return NULL;
|
||||
}
|
||||
while (get_tz_state() == STATE_ENROLL) {
|
||||
ret = vcs_start_capture(vdev, 0);
|
||||
if (ret == -1)
|
||||
goto out;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(int)));
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(int)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_cmd->cmd = vfmEnrollAddImage;
|
||||
resp->data[0] = 0x8;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(int)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret) {
|
||||
ALOGE("%s:send vfmEnrollAddImage error", __FUNCTION__);
|
||||
set_tz_state(STATE_IDLE);
|
||||
send_error_notice(vdev, FINGERPRINT_ERROR_UNABLE_TO_PROCESS);
|
||||
return NULL;
|
||||
}
|
||||
if (resp->result != 0) {
|
||||
send_acquired_notice(vdev, resp->result);
|
||||
continue;
|
||||
}
|
||||
count--;
|
||||
if (resp->data[2] == 0x1)
|
||||
count = 0;
|
||||
if (resp->data[2] != 0x1 && count == 0)
|
||||
count = 1;
|
||||
send_enroll_notice(vdev, idx, count);
|
||||
if (count == 0)
|
||||
break;
|
||||
}
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_base_cmd_t)));
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(*send_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_cmd->cmd = vfmEnrollFinish;
|
||||
send_cmd->len = AUTH_SESSION_TOKEN_LENGTH;
|
||||
resp->data[0] = 0x2845;
|
||||
memcpy(&send_cmd->data, &tz.auth_session_token, AUTH_SESSION_TOKEN_LENGTH);
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("Send vfmEnrollFinish error");
|
||||
}
|
||||
memcpy(&tz.finger[idx].data, &resp->data[2], FINGER_DATA_MAX_LENGTH);
|
||||
for (i = 0; i < 2; i++) {
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(*send_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_cmd->cmd = vfmPayloadBind;
|
||||
send_cmd->len = 0x1;
|
||||
send_cmd->zero = 0x7;
|
||||
sprintf(&send_cmd->data[4], "User_0");
|
||||
if (i == 1) {
|
||||
resp->data[0] = 0x50;
|
||||
}
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
}
|
||||
if (ret || resp->result) {
|
||||
ALOGE("Send vfmPayloadBind error");
|
||||
}
|
||||
memcpy(&tz.finger[idx].payload, &resp->data[2], PAYLOAD_MAX_LENGTH);
|
||||
tz.finger[idx].exist = true;
|
||||
db_write_to_db(vdev, false, idx);
|
||||
|
||||
// We may not need to send vfmEnrollmentPasswordSet.
|
||||
for (i = 0; i < 2; i++) {
|
||||
trust_zone_3x_cmd_t *send_3x_cmd = NULL;
|
||||
send_3x_cmd = (trust_zone_3x_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_3x_cmd_t)));
|
||||
memset(send_3x_cmd, 0, QSEECOM_ALIGN(sizeof(*send_3x_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_3x_cmd->cmd = vfmEnrollmentPasswordSet;
|
||||
send_3x_cmd->len = AUTH_SESSION_TOKEN_LENGTH;
|
||||
memcpy(&send_3x_cmd->data, &tz.auth_session_token, AUTH_SESSION_TOKEN_LENGTH);
|
||||
if (i == 0) {
|
||||
resp->data[0] = 0x90;
|
||||
} else {
|
||||
resp->data[0] = 0x80;
|
||||
}
|
||||
ret = QSEECom_send_cmd(handle, send_3x_cmd, QSEECOM_ALIGN(sizeof(*send_3x_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
}
|
||||
if (ret || resp->result) {
|
||||
ALOGE("Send vfmEnrollmentPasswordSet error");
|
||||
}
|
||||
out:
|
||||
set_tz_state(STATE_IDLE);
|
||||
sensor_uninit();
|
||||
vcs_uninit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* vcs_timeout(void* vdev) {
|
||||
struct timeval now;
|
||||
struct timespec outtime;
|
||||
int ret = 0;
|
||||
|
||||
pthread_mutex_lock(&tz.timeout.lock);
|
||||
gettimeofday(&now, NULL);
|
||||
outtime.tv_sec = now.tv_sec + tz.timeout.timeout;
|
||||
outtime.tv_nsec = now.tv_usec * 1000;
|
||||
ret = pthread_cond_timedwait(&tz.timeout.cond, &tz.timeout.lock, &outtime);
|
||||
pthread_mutex_unlock(&tz.timeout.lock);
|
||||
|
||||
if (ret == ETIMEDOUT) {
|
||||
ALOGI("Enroll timeout! Exit!");
|
||||
int flag = 0;
|
||||
if (get_tz_state() != STATE_IDLE && get_tz_state() != STATE_CANCEL) {
|
||||
set_tz_state(STATE_CANCEL);
|
||||
ioctl(sensor.fd, VFSSPI_IOCTL_SET_DRDY_INT, &flag);
|
||||
while (1) {
|
||||
usleep(100000);
|
||||
if (get_tz_state() == STATE_IDLE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
send_error_notice(vdev, FINGERPRINT_ERROR_TIMEOUT);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int vcs_start_authenticate(void *vdev) {
|
||||
int times = 0;
|
||||
for (times = 0; times < 5; times++)
|
||||
if (get_tz_state() != STATE_IDLE) {
|
||||
ALOGE("%s:Sensor is busy!", __FUNCTION__);
|
||||
if (times < 4) {
|
||||
usleep(100000);
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
set_tz_state(STATE_SCAN);
|
||||
int ret = 0;
|
||||
|
||||
sensor_init();
|
||||
|
||||
ret = vcs_init();
|
||||
if (ret) return ret;
|
||||
ret = pthread_create(&tz.auth_thread, NULL, vcs_authenticate, vdev);
|
||||
if (ret) {
|
||||
ALOGE("Can't create authenticate thread!!");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vcs_start_enroll(void *vdev, uint32_t timeout) {
|
||||
if (get_tz_state() != STATE_IDLE) {
|
||||
ALOGE("%s:Sensor is busy!", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
set_tz_state(STATE_ENROLL);
|
||||
int ret = 0;
|
||||
|
||||
sensor_init();
|
||||
|
||||
ret = vcs_init();
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
ret = pthread_create(&tz.enroll_thread, NULL, vcs_enroll, vdev);
|
||||
if (ret) {
|
||||
ALOGE("Can't create enroll thread!!");
|
||||
return ret;
|
||||
}
|
||||
if (timeout) {
|
||||
tz.timeout.timeout = timeout;
|
||||
ret = pthread_create(&tz.timeout.timeout_thread, NULL, vcs_timeout, vdev);
|
||||
if (ret) {
|
||||
ALOGE("Can't create timeout thread!!");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vcs_get_enrolled_finger_num() {
|
||||
int num = 0;
|
||||
int idx = 1;
|
||||
for (idx = 1; idx <= MAX_NUM_FINGERS; idx++)
|
||||
if (tz.finger[idx].exist)
|
||||
num++;
|
||||
ALOGV("%s: num=%d", __FUNCTION__, num);
|
||||
return num;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: vendorGetAuthToken
|
||||
*/
|
||||
int vcs_update_auth_token() {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_vendor_cmd_t *send_vendor_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
send_vendor_cmd = (trust_zone_vendor_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_vendor_cmd_t)));
|
||||
int i = 0;
|
||||
|
||||
for (i = 0;i < 2; i++) {
|
||||
memset(send_vendor_cmd, 0, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_vendor_cmd->cmd = vfmVendorDefinedOperation;
|
||||
send_vendor_cmd->vendor_cmd = vendorGetAuthToken;
|
||||
if (i == 1) {
|
||||
resp->data[0] = 0x80;
|
||||
}
|
||||
ret = QSEECom_send_cmd(handle, send_vendor_cmd, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
}
|
||||
if (resp->result) {
|
||||
ALOGE("send vendorGetAuthToken failed, qsapp result=%d", resp->result);
|
||||
return resp->result;
|
||||
}
|
||||
memcpy(&tz.auth_token, &resp->data[2], AUTH_TOKEN_LENGTH);
|
||||
ALOGV("Sended vendorGetAuthToken");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: vfmAuthSessionBegin
|
||||
*/
|
||||
|
||||
int vcs_start_auth_session() {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_base_cmd_t *send_cmd = NULL;
|
||||
trust_zone_vendor_cmd_t *send_vendor_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
send_cmd = (trust_zone_base_cmd_t *)handle->ion_sbuffer;
|
||||
send_vendor_cmd = (trust_zone_vendor_cmd_t *)handle->ion_sbuffer;
|
||||
int i = 0;
|
||||
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(int)));
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(int)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_cmd->cmd = vfmAuthSessionBegin;
|
||||
resp->data[0] = AUTH_SESSION_TOKEN_LENGTH;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(int)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("send vfmAuthSessionBegin failed, qsapp result=%d", resp->result);
|
||||
return ret;
|
||||
}
|
||||
memcpy(&tz.auth_session_token, &resp->data[2], AUTH_SESSION_TOKEN_LENGTH);
|
||||
tz.auth_session_opend = true;
|
||||
ALOGV("Sended vfmAuthSessionBegin");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: vfmAuthSessionEnd
|
||||
*/
|
||||
|
||||
int vcs_stop_auth_session() {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_base_cmd_t *send_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
send_cmd = (trust_zone_base_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(int)));
|
||||
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(int)) + QSEECOM_ALIGN(sizeof(int)));
|
||||
send_cmd->cmd = vfmAuthSessionEnd;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(int)), resp, QSEECOM_ALIGN(sizeof(int)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("send vfmAuthSessionEnd failed, qsapp result=%d", resp->result);
|
||||
}
|
||||
memset(tz.auth_session_token, 0, AUTH_SESSION_TOKEN_LENGTH);
|
||||
tz.auth_session_opend = false;
|
||||
ALOGV("Sended vfmAuthSessionEnd");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: 1.vfmInitialize
|
||||
* 2.vendorEnterAuthSession
|
||||
* 3.vfmDeviceInitialize
|
||||
* 4.vfmDeviceCalibrate
|
||||
*/
|
||||
|
||||
int vcs_resume() {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_base_cmd_t *send_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
int ret = 0;
|
||||
send_cmd = (trust_zone_base_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_base_cmd_t)));
|
||||
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(*send_cmd)) + QSEECOM_ALIGN(sizeof(int)));
|
||||
send_cmd->cmd = vfmInitialize;
|
||||
send_cmd->len = 4;
|
||||
send_cmd->data[0] = 2;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(int)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("send vfmInitialize failed, qsapp result=%d", resp->result);
|
||||
return ret;
|
||||
}
|
||||
ALOGV("Sended vfmInitialize");
|
||||
|
||||
if (tz.auth_session_opend) {
|
||||
trust_zone_vendor_cmd_t *send_vendor_cmd = NULL;
|
||||
send_vendor_cmd = (trust_zone_vendor_cmd_t *)handle->ion_sbuffer;
|
||||
memset(send_vendor_cmd, 0, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_vendor_cmd->cmd = vfmVendorDefinedOperation;
|
||||
send_vendor_cmd->vendor_cmd = vendorEnterAuthSession;
|
||||
send_vendor_cmd->len = 0x70;
|
||||
memcpy(&send_vendor_cmd->data, &tz.auth_token, 0x70);
|
||||
ret = QSEECom_send_cmd(handle, send_vendor_cmd, QSEECOM_ALIGN(sizeof(*send_vendor_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("send EnterAuthSession failed, qsapp result=%d", resp->result);
|
||||
return resp->result;
|
||||
}
|
||||
}
|
||||
ALOGV("Sended EnterAuthSession");
|
||||
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(*send_cmd)) + QSEECOM_ALIGN(sizeof(int)));
|
||||
send_cmd->cmd = vfmDeviceInitialize;
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(int)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("send vfmDeviceInitialize failed, qsapp result=%d", resp->result);
|
||||
return ret;
|
||||
}
|
||||
ALOGV("Sended vfmDeviceInitialize");
|
||||
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(*send_cmd)) + QSEECOM_ALIGN(sizeof(*resp)));
|
||||
send_cmd->cmd = vfmDeviceCalibrate;
|
||||
send_cmd->data[0] = 0xc0;
|
||||
send_cmd->data[1] = 0x12;
|
||||
resp->data[0] = CALIBRATE_DATA_MAX_LENGTH;
|
||||
if (tz.calibrate_len) {
|
||||
send_cmd->len = tz.calibrate_len;
|
||||
memcpy(&send_cmd->data[4], &tz.calibrate_data, tz.calibrate_len);
|
||||
} else {
|
||||
send_cmd->len = 0x10;
|
||||
}
|
||||
ret = QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)));
|
||||
if (ret || resp->result) {
|
||||
ALOGE("send vfmDeviceCalibrate failed, qsapp result=%d", resp->result);
|
||||
return ret;
|
||||
}
|
||||
if (tz.calibrate_len == 0) {
|
||||
tz.calibrate_len = resp->data[3] + 0xf;
|
||||
memcpy(&tz.calibrate_data, &resp->data[2], tz.calibrate_len);
|
||||
}
|
||||
ALOGV("Sended vfmDeviceCalibrate");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* cmd: vfmUninitialize
|
||||
* set bandwidth to low and shutdown app
|
||||
*/
|
||||
|
||||
int vcs_uninit() {
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
trust_zone_base_cmd_t *send_cmd = NULL;
|
||||
trust_zone_normal_result_t *resp = NULL;
|
||||
send_cmd = (trust_zone_base_cmd_t *)handle->ion_sbuffer;
|
||||
resp = (trust_zone_normal_result_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(trust_zone_base_cmd_t)));
|
||||
|
||||
if (tz.auth_session_opend) {
|
||||
vcs_update_auth_token();
|
||||
}
|
||||
|
||||
memset(send_cmd, 0, QSEECOM_ALIGN(sizeof(int)) + QSEECOM_ALIGN(sizeof(int)));
|
||||
send_cmd->cmd = vfmUninitialize;
|
||||
QSEECom_send_cmd(handle, send_cmd, QSEECOM_ALIGN(sizeof(int)), resp, QSEECOM_ALIGN(sizeof(int)));
|
||||
QSEECom_set_bandwidth(handle, false);
|
||||
QSEECom_shutdown_app((struct QSEECom_handle **)&tz.qhandle);
|
||||
tz.init = false;
|
||||
set_tz_state(STATE_IDLE);
|
||||
ALOGV("Closed securefp qsapp");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* start app and set bandwidth to high
|
||||
* Call vcs_resume
|
||||
*/
|
||||
|
||||
int vcs_init() {
|
||||
int ret = 0;
|
||||
if (tz.init) {
|
||||
ALOGI("securefp qsapp is already running!");
|
||||
return ret;
|
||||
}
|
||||
ret = QSEECom_start_app((struct QSEECom_handle **)&tz.qhandle,
|
||||
"/firmware/image", "securefp", SB_LENGTH);
|
||||
if (ret) {
|
||||
ALOGE("Loading securefp app failed");
|
||||
return -1;
|
||||
}
|
||||
struct QSEECom_handle *handle = (struct QSEECom_handle *)(tz.qhandle);
|
||||
ret = QSEECom_set_bandwidth(handle, true);
|
||||
if (ret) {
|
||||
ALOGE("Set bandwidth failed");
|
||||
return -1;
|
||||
}
|
||||
tz.init = true;
|
||||
ALOGV("securefp qsapp init success!");
|
||||
ret = vcs_resume();
|
||||
return ret;
|
||||
}
|
136
fingerprint/fingerprint_tz.h
Normal file
136
fingerprint/fingerprint_tz.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||
* may not use this file except in compliance with the License. You may
|
||||
* obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
#ifndef __FINGERPRINT_TZ_H_
|
||||
#define __FINGERPRINT_TZ_H_
|
||||
|
||||
#include "fingerprint_common.h"
|
||||
#include "QSEEComAPI.h"
|
||||
|
||||
/* QSEE cmd */
|
||||
typedef enum trust_zone_cmd_id_t {
|
||||
vfmProvision = 0x1,
|
||||
vfmInitialize = 0x2,
|
||||
vfmUninitialize = 0x3,
|
||||
vfmDeviceInitialize = 0x4,
|
||||
vfmDeviceCalibrate = 0x5,
|
||||
vfmAuthSessionBegin = 0x6,
|
||||
vfmAuthSessionEnd = 0x7,
|
||||
vfmCaptureStart = 0x8,
|
||||
vfmCaptureReadData = 0x9,
|
||||
vfmCaptureProcessData = 0xa,
|
||||
vfmCaptureAbort = 0xb,
|
||||
vfmCaptureGetStatus = 0xc,
|
||||
/* QSEE cmd id 0xd is unused. */
|
||||
vfmCaptureFlushImage = 0xe,
|
||||
vfmEnrollBegin = 0xf,
|
||||
vfmEnrollAddImage = 0x10,
|
||||
vfmEnrollFinish = 0x11,
|
||||
vfmEnrollmentPasswordSet = 0x12,
|
||||
vfmEnrollmentPasswordVerify = 0x13,
|
||||
vfmMatchImageToTemplates = 0x14,
|
||||
vfmPayloadBind = 0x15,
|
||||
vfmPayloadRelease = 0x16,
|
||||
vfmVendorDefinedOperation = 0x17
|
||||
}trust_zone_cmd_id_t;
|
||||
|
||||
typedef enum trust_zone_vendor_cmd_id_t {
|
||||
vendorUnknown0 = 0x0,
|
||||
vendorGetVersion = 0x1,//0x10
|
||||
vendorUnknownA = 0xa,
|
||||
vendorGetAuthToken = 0x14,
|
||||
vendorEnterAuthSession = 0x15,
|
||||
vendorUpdateCalData = 0x17
|
||||
}trust_zone_vendor_cmd_id_t;
|
||||
|
||||
typedef struct trust_zone_normal_cmd_t {
|
||||
trust_zone_cmd_id_t cmd;
|
||||
int len;
|
||||
int zero;
|
||||
char data[BUFFER_LENGTH - 12];
|
||||
}trust_zone_base_cmd_t;
|
||||
|
||||
typedef struct trust_zone_vendor_cmd_t {
|
||||
trust_zone_cmd_id_t cmd;
|
||||
trust_zone_vendor_cmd_id_t vendor_cmd;
|
||||
int len;
|
||||
int zero;
|
||||
char data[BUFFER_LENGTH - 16];
|
||||
}trust_zone_vendor_cmd_t;
|
||||
|
||||
typedef struct trust_zone_2x_cmd_t {
|
||||
trust_zone_cmd_id_t cmd;
|
||||
int len;
|
||||
int zero;
|
||||
char data[BUFFER_LENGTH * 2 - 12];
|
||||
}trust_zone_2x_cmd_t;
|
||||
|
||||
typedef struct trust_zone_3x_cmd_t {
|
||||
trust_zone_cmd_id_t cmd;
|
||||
int len;
|
||||
int zero;
|
||||
char data[BUFFER_LENGTH * 3 - 12];
|
||||
}trust_zone_3x_cmd_t;
|
||||
|
||||
typedef struct trust_zone_5x_cmd_t { //only use on vfmMatchImageToTemplates
|
||||
trust_zone_cmd_id_t cmd;
|
||||
int len;
|
||||
int zero;
|
||||
int unknown[2];
|
||||
time_t time_now;
|
||||
char data[563304];
|
||||
}trust_zone_5x_cmd_t;
|
||||
|
||||
typedef struct trust_zone_normal_result_t {
|
||||
int zero;
|
||||
int result;
|
||||
int data[BUFFER_LENGTH/4 - 2];
|
||||
}trust_zone_normal_result_t;
|
||||
|
||||
typedef struct trust_zone_2x_result_t {
|
||||
int zero;
|
||||
int result;
|
||||
int data[(BUFFER_LENGTH * 2)/4 - 2];
|
||||
}trust_zone_2x_result_t;
|
||||
|
||||
#define FINGERPRINT_ERROR_HW_UNAVAILABLE (1)
|
||||
#define FINGERPRINT_ERROR_UNABLE_TO_PROCESS (2)
|
||||
#define FINGERPRINT_ERROR_TIMEOUT (3)
|
||||
#define FINGERPRINT_ERROR_NO_SPACE (4)
|
||||
#define FINGERPRINT_ERROR_CANCELED (5)
|
||||
#define FINGERPRINT_ERROR_UNABLE_TO_REMOVE (6)
|
||||
#define FINGERPRINT_ERROR_VENDOR_BASE (1000)
|
||||
|
||||
worker_state_t get_tz_state();
|
||||
void set_tz_state(worker_state_t state);
|
||||
|
||||
int vcs_update_cal_data();
|
||||
int vcs_check_state();
|
||||
int vcs_start_capture();
|
||||
void* vcs_authenticate(void* vdev);
|
||||
void* vcs_enroll(void* vdev);
|
||||
int vcs_start_authenticate(void *vdev);
|
||||
int vcs_start_enroll(void *vdev, uint32_t timeout);
|
||||
int vcs_get_enrolled_finger_num();
|
||||
int vcs_update_auth_token();
|
||||
int vcs_start_auth_session();
|
||||
int vcs_stop_auth_session();
|
||||
int vcs_resume();
|
||||
int vcs_uninit();
|
||||
int vcs_init();
|
||||
|
||||
#endif /* __FINGERPRINT_TZ_H_ */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
*
|
||||
|
@ -16,101 +16,30 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/fingerprint.h>
|
||||
#include "fingerprint_common.h"
|
||||
#include "vfs61xx_ioctl.h"
|
||||
|
||||
#define CALL_BASE 0
|
||||
#define FINGER_DATABASE_FILENAME "/data/validity/finger.db"
|
||||
#define SAMSUNG_FP_DB_PATH "/data/validity/template.db"
|
||||
#define SENSOR_FILE_NAME "/dev/vfsspi"
|
||||
#define MAX_DATABASE_CMD 255
|
||||
|
||||
#define CALL_INITSERVICE 1
|
||||
#define CALL_ENROLL 2
|
||||
//userId ,fingerIndex
|
||||
#define CALL_CANCEL 3
|
||||
#define CALL_REMOVE 4
|
||||
//userId ,fingerIndex
|
||||
#define CALL_IDENTIFY 5
|
||||
//userId
|
||||
#define CALL_GET_ENROLLED_FINGER_LIST 6
|
||||
//userId
|
||||
#define CALL_CLEANUP 7
|
||||
int sensor_uninit();
|
||||
int sensor_init();
|
||||
void sensor_process_signal(int signum);
|
||||
int sensor_register();
|
||||
int sensor_capture_start();
|
||||
|
||||
typedef enum worker_state_t {
|
||||
STATE_IDLE = 0,
|
||||
STATE_ENROLL,
|
||||
STATE_SCAN,
|
||||
STATE_EXIT
|
||||
} worker_state_t;
|
||||
int db_check_and_create_table(void* device);
|
||||
int db_read_to_tz(void *device);
|
||||
int db_write_to_db(void *device, bool remove, int fid);
|
||||
int db_init(void *device);
|
||||
int db_uninit(void *device);
|
||||
|
||||
typedef struct worker_thread_t {
|
||||
pthread_t thread;
|
||||
worker_state_t state;
|
||||
} worker_thread_t;
|
||||
void send_error_notice(void* device, int error_info_int);
|
||||
void send_acquired_notice(void* device, int acquired_ret);
|
||||
void send_enroll_notice(void *device, int fid, int remaining);
|
||||
void send_authenticated_notice(void *device, int fid);
|
||||
void send_remove_notice(void *device, int fid);
|
||||
|
||||
typedef struct vcs_fingerprint_device_t {
|
||||
fingerprint_device_t device; // "inheritance"
|
||||
worker_thread_t listener;
|
||||
uint64_t op_id;
|
||||
uint64_t challenge;
|
||||
uint64_t user_id;
|
||||
uint64_t group_id;
|
||||
uint64_t secure_user_id;
|
||||
uint64_t authenticator_id;
|
||||
uint32_t active_gid;
|
||||
int send_fd; //send to validity service
|
||||
int receive_fd; //recevie from validity service
|
||||
bool init;
|
||||
pthread_mutex_t lock;
|
||||
} vcs_fingerprint_device_t;
|
||||
|
||||
static __inline__ int fd_write(int fd, const void* buff, int len){
|
||||
int len2;
|
||||
do {
|
||||
len2 = write(fd, buff, len);
|
||||
} while (len2 < 0 && errno == EINTR);
|
||||
return len2;
|
||||
}
|
||||
static __inline__ int fd_read(int fd, void* buff, int len){
|
||||
int len2;
|
||||
do {
|
||||
len2 = read(fd, buff, len);
|
||||
} while (len2 < 0 && errno == EINTR);
|
||||
return len2;
|
||||
}
|
||||
|
||||
static void checkinit(vcs_fingerprint_device_t* vdev);
|
||||
static int sendcommand(vcs_fingerprint_device_t* vdev, uint8_t* command, int num);
|
||||
static int getfingermask(vcs_fingerprint_device_t* vdev);
|
||||
static int initService(vcs_fingerprint_device_t* vdev);
|
||||
|
||||
static void send_error_notice(vcs_fingerprint_device_t* vdev, fingerprint_error_t error_info);
|
||||
static void send_acquired_notice(vcs_fingerprint_device_t* vdev, fingerprint_acquired_info_t acquired_info);
|
||||
static void send_enroll_notice(vcs_fingerprint_device_t* vdev, int fid, int remaining);
|
||||
static void send_authenticated_notice(vcs_fingerprint_device_t* vdev, int fid);
|
||||
static void send_remove_notice(vcs_fingerprint_device_t* vdev, int fid);
|
||||
|
||||
static uint64_t get_64bit_rand();
|
||||
static uint64_t fingerprint_get_auth_id(struct fingerprint_device* device);
|
||||
static int fingerprint_set_active_group(struct fingerprint_device *device, uint32_t gid,
|
||||
const char __unused *path);
|
||||
static int fingerprint_authenticate(struct fingerprint_device *device,
|
||||
uint64_t operation_id, __unused uint32_t gid);
|
||||
static int fingerprint_enroll(struct fingerprint_device *device,
|
||||
const hw_auth_token_t *hat,
|
||||
uint32_t __unused gid,
|
||||
uint32_t __unused timeout_sec);
|
||||
static uint64_t fingerprint_pre_enroll(struct fingerprint_device *device);
|
||||
static int fingerprint_post_enroll(struct fingerprint_device* device);
|
||||
static int fingerprint_cancel(struct fingerprint_device *device);
|
||||
static int fingerprint_enumerate(struct fingerprint_device *device,
|
||||
fingerprint_finger_id_t *results, uint32_t *max_size);
|
||||
static int fingerprint_remove(struct fingerprint_device *device,
|
||||
uint32_t __unused gid, uint32_t fid);
|
||||
static int set_notify_callback(struct fingerprint_device *device,
|
||||
fingerprint_notify_t notify);
|
||||
|
||||
static worker_state_t getListenerState(vcs_fingerprint_device_t* dev);
|
||||
static void* listenerSocket(void* data);
|
||||
|
||||
static int fingerprint_close(hw_device_t* device);
|
||||
static int fingerprint_open(const hw_module_t* module, const char __unused *id,
|
||||
hw_device_t** device);
|
||||
|
||||
|
|
206
fingerprint/hash.c
Normal file
206
fingerprint/hash.c
Normal file
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hash.h"
|
||||
|
||||
SHA1Context sha;
|
||||
|
||||
/*
|
||||
* HASH method: SHA1
|
||||
*/
|
||||
|
||||
uint64_t convert_hash_to_number() {
|
||||
uint64_t num = 0;
|
||||
num = ((uint64_t)sha.Message_Digest[0] << 32) + sha.Message_Digest[1];
|
||||
return num;
|
||||
}
|
||||
|
||||
uint64_t hash_file(const char *file_path) {
|
||||
FILE * file;
|
||||
char str[MAX_FILE_LENGTH];
|
||||
int len = 0;
|
||||
file = fopen(file_path, "rb");
|
||||
if (!file)
|
||||
return 1;
|
||||
len = fread(str, sizeof(char), MAX_FILE_LENGTH, file);
|
||||
fclose(file);
|
||||
sha1_hash(str, len);
|
||||
return convert_hash_to_number();
|
||||
}
|
||||
|
||||
uint64_t hash_string(const char *str) {
|
||||
sha1_hash(str, strlen(str));
|
||||
return convert_hash_to_number();
|
||||
}
|
||||
|
||||
void SHA1Reset(SHA1Context *context){
|
||||
context->Length_Low = 0;
|
||||
context->Length_High = 0;
|
||||
context->Message_Block_Index = 0;
|
||||
|
||||
context->Message_Digest[0] = 0x67452301;
|
||||
context->Message_Digest[1] = 0xEFCDAB89;
|
||||
context->Message_Digest[2] = 0x98BADCFE;
|
||||
context->Message_Digest[3] = 0x10325476;
|
||||
context->Message_Digest[4] = 0xC3D2E1F0;
|
||||
|
||||
context->Computed = 0;
|
||||
context->Corrupted = 0;
|
||||
}
|
||||
|
||||
|
||||
int SHA1Result(SHA1Context *context){
|
||||
if (context->Corrupted) {
|
||||
return 0;
|
||||
}
|
||||
if (!context->Computed) {
|
||||
SHA1PadMessage(context);
|
||||
context->Computed = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void SHA1Input(SHA1Context *context,const char *message_array,unsigned length){
|
||||
if (!length) return;
|
||||
|
||||
if (context->Computed || context->Corrupted){
|
||||
context->Corrupted = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
while(length-- && !context->Corrupted){
|
||||
context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF);
|
||||
|
||||
context->Length_Low += 8;
|
||||
|
||||
context->Length_Low &= 0xFFFFFFFF;
|
||||
if (context->Length_Low == 0){
|
||||
context->Length_High++;
|
||||
context->Length_High &= 0xFFFFFFFF;
|
||||
if (context->Length_High == 0) context->Corrupted = 1;
|
||||
}
|
||||
|
||||
if (context->Message_Block_Index == 64){
|
||||
SHA1ProcessMessageBlock(context);
|
||||
}
|
||||
message_array++;
|
||||
}
|
||||
}
|
||||
|
||||
void SHA1ProcessMessageBlock(SHA1Context *context){
|
||||
const unsigned K[] = {0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
|
||||
int t;
|
||||
unsigned temp;
|
||||
unsigned W[80];
|
||||
unsigned A, B, C, D, E;
|
||||
|
||||
for(t = 0; t < 16; t++) {
|
||||
W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
|
||||
W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
|
||||
W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
|
||||
W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
|
||||
}
|
||||
|
||||
for(t = 16; t < 80; t++) W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
|
||||
|
||||
A = context->Message_Digest[0];
|
||||
B = context->Message_Digest[1];
|
||||
C = context->Message_Digest[2];
|
||||
D = context->Message_Digest[3];
|
||||
E = context->Message_Digest[4];
|
||||
|
||||
for(t = 0; t < 20; t++) {
|
||||
temp = SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
|
||||
temp &= 0xFFFFFFFF;
|
||||
E = D;
|
||||
D = C;
|
||||
C = SHA1CircularShift(30,B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
for(t = 20; t < 40; t++) {
|
||||
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
|
||||
temp &= 0xFFFFFFFF;
|
||||
E = D;
|
||||
D = C;
|
||||
C = SHA1CircularShift(30,B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
for(t = 40; t < 60; t++) {
|
||||
temp = SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
|
||||
temp &= 0xFFFFFFFF;
|
||||
E = D;
|
||||
D = C;
|
||||
C = SHA1CircularShift(30,B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
for(t = 60; t < 80; t++) {
|
||||
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
|
||||
temp &= 0xFFFFFFFF;
|
||||
E = D;
|
||||
D = C;
|
||||
C = SHA1CircularShift(30,B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
context->Message_Digest[0] = (context->Message_Digest[0] + A) & 0xFFFFFFFF;
|
||||
context->Message_Digest[1] = (context->Message_Digest[1] + B) & 0xFFFFFFFF;
|
||||
context->Message_Digest[2] = (context->Message_Digest[2] + C) & 0xFFFFFFFF;
|
||||
context->Message_Digest[3] = (context->Message_Digest[3] + D) & 0xFFFFFFFF;
|
||||
context->Message_Digest[4] = (context->Message_Digest[4] + E) & 0xFFFFFFFF;
|
||||
context->Message_Block_Index = 0;
|
||||
}
|
||||
|
||||
void SHA1PadMessage(SHA1Context *context){
|
||||
if (context->Message_Block_Index > 55) {
|
||||
context->Message_Block[context->Message_Block_Index++] = 0x80;
|
||||
while(context->Message_Block_Index < 64) context->Message_Block[context->Message_Block_Index++] = 0;
|
||||
SHA1ProcessMessageBlock(context);
|
||||
while(context->Message_Block_Index < 56) context->Message_Block[context->Message_Block_Index++] = 0;
|
||||
} else {
|
||||
context->Message_Block[context->Message_Block_Index++] = 0x80;
|
||||
while(context->Message_Block_Index < 56) context->Message_Block[context->Message_Block_Index++] = 0;
|
||||
}
|
||||
context->Message_Block[56] = (context->Length_High >> 24 ) & 0xFF;
|
||||
context->Message_Block[57] = (context->Length_High >> 16 ) & 0xFF;
|
||||
context->Message_Block[58] = (context->Length_High >> 8 ) & 0xFF;
|
||||
context->Message_Block[59] = (context->Length_High) & 0xFF;
|
||||
context->Message_Block[60] = (context->Length_Low >> 24 ) & 0xFF;
|
||||
context->Message_Block[61] = (context->Length_Low >> 16 ) & 0xFF;
|
||||
context->Message_Block[62] = (context->Length_Low >> 8 ) & 0xFF;
|
||||
context->Message_Block[63] = (context->Length_Low) & 0xFF;
|
||||
|
||||
SHA1ProcessMessageBlock(context);
|
||||
}
|
||||
|
||||
int sha1_hash(const char *source, int len){
|
||||
SHA1Reset(&sha);
|
||||
SHA1Input(&sha, source, len);
|
||||
|
||||
if (!SHA1Result(&sha)){
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
47
fingerprint/hash.h
Normal file
47
fingerprint/hash.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __HASH_H_
|
||||
#define __HASH_H_
|
||||
|
||||
|
||||
#define SHA1CircularShift(bits,word) ((((word) << (bits)) & 0xFFFFFFFF) | ((word) >> (32-(bits))))
|
||||
#define MAX_FILE_LENGTH (300000)
|
||||
|
||||
typedef struct SHA1Context{
|
||||
unsigned Message_Digest[5];
|
||||
unsigned Length_Low;
|
||||
unsigned Length_High;
|
||||
unsigned char Message_Block[64];
|
||||
int Message_Block_Index;
|
||||
int Computed;
|
||||
int Corrupted;
|
||||
} SHA1Context;
|
||||
|
||||
void SHA1Reset(SHA1Context *);
|
||||
int SHA1Result(SHA1Context *);
|
||||
void SHA1Input( SHA1Context *,const char *,unsigned);
|
||||
|
||||
void SHA1ProcessMessageBlock(SHA1Context *);
|
||||
void SHA1PadMessage(SHA1Context *);
|
||||
int sha1_hash(const char *source, int len);
|
||||
|
||||
uint64_t hash_file(const char *file_path);
|
||||
uint64_t hash_string(const char *str);
|
||||
|
||||
#endif //__HASH_H_
|
115
fingerprint/vfs61xx_ioctl.h
Normal file
115
fingerprint/vfs61xx_ioctl.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Copied from kernel - drivers/fingerprint/vfs61xx.h
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef VFS61XX_IOCTL_H_
|
||||
#define VFS61XX_IOCTL_H_
|
||||
|
||||
/* See kernel/include/linux/fprint_secure.h */
|
||||
#ifndef ENABLE_SENSORS_FPRINT_SECURE
|
||||
#define ENABLE_SENSORS_FPRINT_SECURE
|
||||
#endif
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
/* Pass to VFSSPI_IOCTL_REGISTER_DRDY_SIGNAL command */
|
||||
struct vfsspi_iocRegSignal {
|
||||
/* Process ID to which SPI driver sends signal
|
||||
* indicating that DRDY is asserted */
|
||||
int userPID;
|
||||
int signalID; /* Signal number */
|
||||
};
|
||||
|
||||
/* Magic number of IOCTL command */
|
||||
#define VFSSPI_IOCTL_MAGIC 'k'
|
||||
|
||||
/*
|
||||
* IOCTL commands definitions
|
||||
*/
|
||||
|
||||
#ifndef ENABLE_SENSORS_FPRINT_SECURE
|
||||
/* Transmit data to the device
|
||||
and retrieve data from it simultaneously */
|
||||
#define VFSSPI_IOCTL_RW_SPI_MESSAGE \
|
||||
_IOWR(VFSSPI_IOCTL_MAGIC, 1, unsigned int)
|
||||
#endif
|
||||
/* Hard reset the device */
|
||||
#define VFSSPI_IOCTL_DEVICE_RESET \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 2)
|
||||
/* Set the baud rate of SPI master clock */
|
||||
#define VFSSPI_IOCTL_SET_CLK \
|
||||
_IOW(VFSSPI_IOCTL_MAGIC, 3, unsigned int)
|
||||
#ifndef ENABLE_SENSORS_FPRINT_SECURE
|
||||
/* Get level state of DRDY GPIO */
|
||||
#define VFSSPI_IOCTL_CHECK_DRDY \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 4)
|
||||
#endif
|
||||
/* Register DRDY signal. It is used by SPI driver
|
||||
* for indicating host that DRDY signal is asserted. */
|
||||
#define VFSSPI_IOCTL_REGISTER_DRDY_SIGNAL \
|
||||
_IOW(VFSSPI_IOCTL_MAGIC, 5, unsigned int)
|
||||
/* Store the user data into the SPI driver. Currently user data is a
|
||||
* device info data, which is obtained from announce packet. */
|
||||
#ifndef ENABLE_SENSORS_FPRINT_SECURE
|
||||
#define VFSSPI_IOCTL_SET_USER_DATA \
|
||||
_IOW(VFSSPI_IOCTL_MAGIC, 6, unsigned int)
|
||||
#endif
|
||||
#ifndef ENABLE_SENSORS_FPRINT_SECURE
|
||||
/* Retrieve user data from the SPI driver*/
|
||||
#define VFSSPI_IOCTL_GET_USER_DATA \
|
||||
_IOWR(VFSSPI_IOCTL_MAGIC, 7, unsigned int)
|
||||
#endif
|
||||
/* Enable/disable DRDY interrupt handling in the SPI driver */
|
||||
#define VFSSPI_IOCTL_SET_DRDY_INT \
|
||||
_IOW(VFSSPI_IOCTL_MAGIC, 8, unsigned int)
|
||||
/* Put device in Low power mode */
|
||||
#define VFSSPI_IOCTL_DEVICE_SUSPEND \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 9)
|
||||
#ifndef ENABLE_SENSORS_FPRINT_SECURE
|
||||
/* Indicate the fingerprint buffer size for read */
|
||||
#define VFSSPI_IOCTL_STREAM_READ_START \
|
||||
_IOW(VFSSPI_IOCTL_MAGIC, 10, unsigned int)
|
||||
/* Indicate that fingerprint acquisition is completed */
|
||||
#define VFSSPI_IOCTL_STREAM_READ_STOP \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 11)
|
||||
/* Retrieve supported SPI baud rate table */
|
||||
#define VFSSPI_IOCTL_GET_FREQ_TABLE \
|
||||
_IOWR(VFSSPI_IOCTL_MAGIC, 12, unsigned int)
|
||||
#endif
|
||||
/* Turn on the power to the sensor */
|
||||
#define VFSSPI_IOCTL_POWER_ON \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 13)
|
||||
/* Turn off the power to the sensor */
|
||||
#define VFSSPI_IOCTL_POWER_OFF \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 14)
|
||||
#ifdef ENABLE_SENSORS_FPRINT_SECURE
|
||||
/* To disable spi core clock */
|
||||
#define VFSSPI_IOCTL_DISABLE_SPI_CLOCK \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 15)
|
||||
/* To set SPI configurations like gpio, clks */
|
||||
#define VFSSPI_IOCTL_SET_SPI_CONFIGURATION \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 16)
|
||||
/* To reset SPI configurations */
|
||||
#define VFSSPI_IOCTL_RESET_SPI_CONFIGURATION \
|
||||
_IO(VFSSPI_IOCTL_MAGIC, 17)
|
||||
#endif
|
||||
/* get sensor orienation from the SPI driver*/
|
||||
#define VFSSPI_IOCTL_GET_SENSOR_ORIENT \
|
||||
_IOR(VFSSPI_IOCTL_MAGIC, 18, unsigned int)
|
||||
#endif /* VFS61XX_IOCTL_H_ */
|
3
klte.mk
3
klte.mk
|
@ -76,8 +76,7 @@ PRODUCT_PACKAGES += \
|
|||
# Fingerprint
|
||||
PRODUCT_PACKAGES += \
|
||||
fingerprintd \
|
||||
fingerprint.msm8974 \
|
||||
ValidityService
|
||||
fingerprint.msm8974
|
||||
|
||||
# Gello
|
||||
PRODUCT_PACKAGES += \
|
||||
|
|
|
@ -1074,12 +1074,6 @@ service sec-sh /system/bin/sh /system/etc/init.sec.boot.sh
|
|||
user root
|
||||
oneshot
|
||||
|
||||
# SENSOR FRAMEWORK : starts fingerprintService
|
||||
service vcsFPService /system/bin/vcsFPService
|
||||
class late_start
|
||||
user system
|
||||
group system
|
||||
|
||||
on property:persist.sys.ssr.restart_level=1
|
||||
write /sys/module/subsystem_restart/parameters/restart_level 1
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
/dev/block/platform/msm_sdcc.1/by-name/efs u:object_r:modem_efs_partition_device:s0
|
||||
|
||||
# Fingerprint
|
||||
/system/bin/vcsFPService u:object_r:vcs_exec:s0
|
||||
/data/validity(/.*)? u:object_r:vcs_data_file:s0
|
||||
/dev/validity(/.*)? u:object_r:vcs_device:s0
|
||||
/dev/vfsspi u:object_r:vcs_device:s0
|
||||
|
|
|
@ -1 +1,13 @@
|
|||
allow fingerprintd system_app:unix_stream_socket { connectto read write setopt };
|
||||
allow fingerprintd vcs_data_file:dir create_dir_perms;
|
||||
allow fingerprintd vcs_data_file:file create_file_perms;
|
||||
|
||||
allow fingerprintd vcs_device:dir create_dir_perms;
|
||||
allow fingerprintd vcs_device:file create_file_perms;
|
||||
allow fingerprintd vcs_device:fifo_file create_file_perms;
|
||||
allow fingerprintd vcs_device:chr_file create_file_perms;
|
||||
|
||||
allow fingerprintd tee_device:chr_file rw_file_perms;
|
||||
|
||||
allow fingerprintd firmware_file:dir r_dir_perms;
|
||||
allow fingerprintd firmware_file:file r_file_perms;
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
# For com.validity.fingerprint
|
||||
allow system_app vcs:process signull;
|
||||
allow system_app vcs_data_file:dir r_dir_perms;
|
||||
allow system_app vcs_data_file:file r_file_perms;
|
||||
allow system_app vcs_device:dir r_dir_perms;
|
||||
allow system_app vcs_device:file r_file_perms;
|
||||
allow system_app vcs_device:fifo_file create_file_perms;
|
|
@ -1,22 +0,0 @@
|
|||
type vcs, domain;
|
||||
type vcs_exec, exec_type, file_type;
|
||||
|
||||
# vcs
|
||||
init_daemon_domain(vcs)
|
||||
binder_use(vcs)
|
||||
|
||||
allow vcs system_app:process signull;
|
||||
|
||||
allow vcs vcs_data_file:dir create_dir_perms;
|
||||
allow vcs vcs_data_file:file create_file_perms;
|
||||
|
||||
allow vcs vcs_device:dir create_dir_perms;
|
||||
allow vcs vcs_device:file create_file_perms;
|
||||
allow vcs vcs_device:fifo_file create_file_perms;
|
||||
allow vcs vcs_device:chr_file create_file_perms;
|
||||
|
||||
allow vcs tee_device:chr_file rw_file_perms;
|
||||
|
||||
allow vcs firmware_file:dir r_dir_perms;
|
||||
allow vcs firmware_file:file r_file_perms;
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
# Copyright (C) 2016 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_PACKAGE_NAME := ValidityService
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
|
||||
LOCAL_AAPT_FLAGS := --auto-add-overlay
|
||||
|
||||
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
|
||||
|
||||
LOCAL_CERTIFICATE := platform
|
||||
LOCAL_PRIVILEGED_MODULE := true
|
||||
|
||||
LOCAL_JACK_ENABLED := disabled
|
||||
|
||||
include $(BUILD_PACKAGE)
|
|
@ -1,37 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
package="com.validity.fingerprint"
|
||||
coreApp="true"
|
||||
android:sharedUserId="android.uid.system">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
|
||||
|
||||
<application
|
||||
android:name=".ValidityServiceStarter"
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/icon"
|
||||
android:persistent="true"
|
||||
android:label="@string/app_name">
|
||||
|
||||
<service android:name=".ValidityService"
|
||||
android:exported="true" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,2 +0,0 @@
|
|||
-verbose
|
||||
-keep class com.validity.fingerprint.* {*;}
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
|
@ -1,20 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The CyanogenMod Project
|
||||
Copyright (C) 2016 The Mokee Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="app_name">Validity service</string>
|
||||
</resources>
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
|
||||
public class ConsumerInfo {
|
||||
public Object info;
|
||||
public int type;
|
||||
|
||||
public ConsumerInfo() {
|
||||
}
|
||||
|
||||
public ConsumerInfo(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class EnrollCaptureStatus {
|
||||
|
||||
public int badSwipes;
|
||||
public int cumulativeCoverageMap;
|
||||
public int currentCoverageMap;
|
||||
public int imageQuality;
|
||||
public int positionFeedback;
|
||||
public int progress;
|
||||
public int templateResult;
|
||||
public int totalSwipes;
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class EnrollUser {
|
||||
public int fingerIndex;
|
||||
public int mode;
|
||||
public String userId;
|
||||
|
||||
public EnrollUser() {
|
||||
mode = 1;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
public class Fingerprint extends FingerprintCore {
|
||||
|
||||
public static final int VCS_ENROLL_MODE_DEFAULT = 1;
|
||||
public static final int VCS_ENROLL_MODE_REENROLL = 2;
|
||||
public static final int VCS_ENROLL_MODE_SECONDARY = 3;
|
||||
|
||||
public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_MIDDLE = 11;
|
||||
public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_MIDDLE_FULL = 12;
|
||||
public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_LEFT = 21;
|
||||
public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_RIGHT = 31;
|
||||
public static final int VCS_FINGER_POSITION_FEEDBACK_SWIPE_ANY = 41;
|
||||
|
||||
public static final int VCS_NOTIFY_SNSR_TEST_CONTINUE = 1;
|
||||
public static final int VCS_NOTIFY_SNSR_TEST_STOP = 2;
|
||||
public static final int VCS_NOTIFY_ENROLL_BEGIN = 3;
|
||||
public static final int VCS_NOTIFY_ENROLL_END = 4;
|
||||
|
||||
public static final int VCS_REQUEST_PROCESS_FIDO = 1;
|
||||
public static final int VCS_REQUEST_PROCESS_ALIPAY = 2;
|
||||
public static final int VCS_REQUEST_COMMAND_SENSOR_TEST = 11;
|
||||
public static final int VCS_REQUEST_GET_SENSOR_INFO = 12;
|
||||
public static final int VCS_REQUEST_GET_ENROLL_REPEAT_COUNT = 13;
|
||||
private static final int VCS_REQUEST_ENABLE_WOF = 21;
|
||||
private static final int VCS_REQUEST_GET_WOF_STATE = 22;
|
||||
|
||||
public static final int VCS_SENSOR_STATUS_OK = 0;
|
||||
public static final int VCS_SENSOR_STATUS_WORKING = 46;
|
||||
public static final int VCS_SENSOR_STATUS_INITIALISING = 358;
|
||||
public static final int VCS_SENSOR_STATUS_INITIALIZING = 358;
|
||||
public static final int VCS_SENSOR_STATUS_OUT_OF_ORDER = 360;
|
||||
public static final int VCS_SENSOR_STATUS_MALFUNCTIONED = 534;
|
||||
public static final int VCS_SENSOR_STATUS_FAILURE = 535;
|
||||
|
||||
public static final int VCS_WOF_STATE_INACTIVE = 0;
|
||||
public static final int VCS_WOF_STATE_ACTIVE = 1;
|
||||
|
||||
private native int jniEnableSensorDevice(int enable);
|
||||
private native int jniEnrollUser(Object enrollInfo);
|
||||
private native int jniEnrollUser(String userId, int fingerIndex, int mode);
|
||||
private native int jniEnrollUser(String userId, String appData, int fingerIndex);
|
||||
private native int jniGetSensorStatus();
|
||||
private native int jniNotify(int code, Object data);
|
||||
private native int jniProcessFIDO(byte requestData[], VcsByteArray responseData);
|
||||
private native int jniReEnrollUser(String userId, String appData, int fingerIndex, int mode);
|
||||
private native int jniRemoveEnrolledFinger(Object enrollInfo);
|
||||
private native int jniRemoveEnrolledFinger(String userId, int fingerIndex);
|
||||
private native int jniRequest(int command, Object data);
|
||||
private native int jniSetPassword(String userId, byte abyte0[], byte newPwdHash[]); // What is abyte0 means?
|
||||
private native int jniVerifyPassword(String userId, byte pwdHash[]);
|
||||
|
||||
public Fingerprint(Context ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
public Fingerprint(Context ctx, FingerprintCore.EventListener listener) {
|
||||
super(ctx, listener);
|
||||
}
|
||||
|
||||
public int enableSensorDevice(boolean enable) {
|
||||
if (mOperation != 150)
|
||||
return VCS_RESULT_ALREADY_INPROGRESS;
|
||||
return jniEnableSensorDevice((enable? 1: 0));
|
||||
}
|
||||
|
||||
public int enableWakeOnFinger() {
|
||||
return jniRequest(VCS_REQUEST_ENABLE_WOF, null);
|
||||
}
|
||||
|
||||
public int enroll(EnrollUser enrollInfo) {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation != 150)
|
||||
return ret;
|
||||
ret = jniEnrollUser(enrollInfo);
|
||||
if (ret == VCS_RESULT_OK)
|
||||
mOperation = 151;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int enroll(String userId, int fingerIndex) {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation != 150)
|
||||
return ret;
|
||||
if (null == userId)
|
||||
userId = "";
|
||||
ret = jniEnrollUser(userId, fingerIndex, VCS_ENROLL_MODE_DEFAULT);
|
||||
if (ret == VCS_RESULT_OK)
|
||||
mOperation = 151;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int enroll(String userId, int fingerIndex, int mode) {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation != 150)
|
||||
return ret;
|
||||
if (null == userId)
|
||||
userId = "";
|
||||
ret = jniEnrollUser(userId, fingerIndex, mode);
|
||||
if (ret == VCS_RESULT_OK)
|
||||
mOperation = 151;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int enroll(String userId, String appData, int fingerIndex) {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation != 150)
|
||||
return ret;
|
||||
if (null == userId)
|
||||
userId = "";
|
||||
if (null == appData)
|
||||
appData = "";
|
||||
ret = jniEnrollUser(userId, appData, fingerIndex);
|
||||
if (ret == VCS_RESULT_OK)
|
||||
mOperation = 151;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int enroll(String userId, String appData, int fingerIndex, int mode) {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation != 150)
|
||||
return ret;
|
||||
if (null == userId)
|
||||
userId = "";
|
||||
if (null == appData)
|
||||
appData = "";
|
||||
ret = jniReEnrollUser(userId, appData, fingerIndex, mode);
|
||||
if (ret == VCS_RESULT_OK)
|
||||
mOperation = 151;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getSensorStatus() {
|
||||
if (mOperation != 150)
|
||||
return VCS_RESULT_ALREADY_INPROGRESS;
|
||||
return jniGetSensorStatus();
|
||||
}
|
||||
|
||||
public int getWakeOnFingerState(VcsInt wofState) {
|
||||
if (wofState == null)
|
||||
return VCS_RESULT_INVALID_ARGUMENT;
|
||||
return jniRequest(VCS_REQUEST_GET_WOF_STATE, wofState);
|
||||
}
|
||||
|
||||
public int notify(int code, Object data) {
|
||||
return jniNotify(code, data);
|
||||
}
|
||||
|
||||
public int processFIDO(byte requestData[], VcsByteArray responseData) {
|
||||
if ((requestData == null) || (responseData == null))
|
||||
return VCS_RESULT_INVALID_ARGUMENT;
|
||||
return jniProcessFIDO(requestData, responseData);
|
||||
}
|
||||
|
||||
public int removeEnrolledFinger(RemoveEnroll enrollInfo) {
|
||||
return jniRemoveEnrolledFinger(enrollInfo);
|
||||
}
|
||||
|
||||
public int removeEnrolledFinger(String userId, int fingerIndex) {
|
||||
if (mOperation != 150)
|
||||
return VCS_RESULT_ALREADY_INPROGRESS;
|
||||
if (null == userId)
|
||||
userId = "";
|
||||
return jniRemoveEnrolledFinger(userId, fingerIndex);
|
||||
}
|
||||
|
||||
public int removeEnrolledUser(String userId) {
|
||||
if (mOperation != 150)
|
||||
return VCS_RESULT_ALREADY_INPROGRESS;
|
||||
if (null == userId)
|
||||
userId = "";
|
||||
return jniRemoveEnrolledFinger(userId, FINGER_INDEX_LEFT_THUMB_SECOND);
|
||||
}
|
||||
|
||||
public int request(int command, Object data) {
|
||||
return jniRequest(command, data);
|
||||
}
|
||||
|
||||
public int setPassword(String userId, byte newPwdHash[]) {
|
||||
if (userId == null || newPwdHash == null)
|
||||
return VCS_RESULT_INVALID_ARGUMENT;
|
||||
return jniSetPassword(userId, "".getBytes(), newPwdHash);
|
||||
}
|
||||
|
||||
public int verifyPassword(String userId, byte pwdHash[]) {
|
||||
if (userId == null || pwdHash == null)
|
||||
return VCS_RESULT_INVALID_ARGUMENT;
|
||||
return jniVerifyPassword(userId, pwdHash);
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
public class FingerprintBitmap {
|
||||
public Bitmap fingerprint;
|
||||
public int quality;
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
public class FingerprintCore extends VcsEvents {
|
||||
public static interface EventListener {
|
||||
public abstract void onEvent(FingerprintEvent fingerprintevent);
|
||||
}
|
||||
public static final String API_VERSION = "0.7";
|
||||
public static final String VCS_POLICY_VERSION = "0.1";
|
||||
protected static final boolean DBG = false;
|
||||
protected static final int IDLE = 150;
|
||||
protected static final int ENROLL = 151;
|
||||
protected static final int IDENTIFY = 152;
|
||||
protected static final int STOREDATATOUSER = 153;
|
||||
protected static final int GETDATAFROMUSER = 154;
|
||||
protected static final int REMOVEDATAFROMUSER = 155;
|
||||
protected static final int GETPRINT = 156;
|
||||
protected static final String TAG = "Fingerprint";
|
||||
protected static final String USER_ID = "android";
|
||||
protected int mOperation;
|
||||
private EventListener mEventListener;
|
||||
private String mAppId;
|
||||
private String mUserId;
|
||||
private String mAppKey;
|
||||
private String mKeyData;
|
||||
|
||||
private native int jniCancelOp();
|
||||
private native int jniCleanupVcs();
|
||||
private native int jniGetEnrolledFingerList(String userId, VcsInt fingermask);
|
||||
private native int jniGetFingerprintImage();
|
||||
private native int jniGetFingerprintImageEx(Object info);
|
||||
private native String[] jniGetUserList(VcsInt retCode);
|
||||
private native String jniGetVersion();
|
||||
private native int jniIdentify(String userId);
|
||||
private native int jniInitVcs();
|
||||
private native int jniInitVcs(FingerprintCore fingerprintcore);
|
||||
private native int jniProtect(byte toProtect[], VcsAddInfo addInfo, VcsByteArray protectedData);
|
||||
private native int jniRegisterEventsCB(FingerprintCore fingerprintcore);
|
||||
private native int jniSetDetectFinger(int timeout);
|
||||
private native int jniSetSecurityLevel(int level);
|
||||
private native int jniUnprotect(byte protectedData[], VcsAddInfo addInfo, VcsByteArray unProtectedData);
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("vcsfp");
|
||||
}
|
||||
catch (Throwable e) {
|
||||
Log.e("Fingerprint", "Error loading library libvcsfp: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public FingerprintCore(Context ctx) {
|
||||
mOperation = IDLE;
|
||||
mEventListener = null;
|
||||
mAppId = "";
|
||||
mUserId = "";
|
||||
mAppKey = "";
|
||||
mKeyData = "";
|
||||
jniInitVcs(this);
|
||||
}
|
||||
|
||||
public FingerprintCore(Context ctx, EventListener listener) {
|
||||
mOperation = IDLE;
|
||||
mEventListener = null;
|
||||
mAppId = "";
|
||||
mUserId = "";
|
||||
mAppKey = "";
|
||||
mKeyData = "";
|
||||
VLog.i("init ret="+jniInitVcs(this));
|
||||
mEventListener = listener;
|
||||
}
|
||||
|
||||
private boolean isOperationComplete(int eventId) {
|
||||
if (eventId == VCS_EVT_ENROLL_SUCCESS || eventId == VCS_EVT_IDENTIFY_SUCCESS ||
|
||||
eventId == VCS_EVT_VERIFY_SUCCESS || eventId == VCS_EVT_ENROLL_FAILED ||
|
||||
eventId == VCS_EVT_IDENTIFY_FAILED || eventId == VCS_EVT_VERIFY_FAILED ||
|
||||
eventId == VCS_EVT_GESTURE)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized void FingerprintEventCallback(FingerprintEvent event) {
|
||||
if (event == null) {
|
||||
Log.e("Fingerprint", "FP - EventsCB()::Invalid event data!");
|
||||
return;
|
||||
}
|
||||
if (isOperationComplete(event.eventId)) {
|
||||
Log.i("Fingerprint", "Operation complete, setting to IDLE");
|
||||
this.mOperation = IDLE;
|
||||
}
|
||||
if ((this.mOperation == GETPRINT) && ((event.eventId == VCS_EVT_EIV_FINGERPRINT_CAPTURED) ||
|
||||
(event.eventId == VCS_EVT_SENSOR_FINGERPRINT_CAPTURE_FAILED))) {
|
||||
this.mOperation = IDLE;
|
||||
}
|
||||
if (this.mEventListener != null) {
|
||||
this.mEventListener.onEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
public int cancel() {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation == IDLE)
|
||||
return ret;
|
||||
ret = jniCancelOp();
|
||||
mOperation = IDLE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int cleanUp() {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
mEventListener = null;
|
||||
ret = jniCleanupVcs();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getEnrolledFingerList(String userId, VcsInt fingermask) {
|
||||
if (null == userId)
|
||||
userId = "";
|
||||
int ret = jniGetEnrolledFingerList(userId, fingermask);;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getFingerprintImage(){
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation != IDLE)
|
||||
return ret;
|
||||
ret = jniGetFingerprintImage();
|
||||
if (ret == VCS_RESULT_OK)
|
||||
mOperation = GETPRINT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getFingerprintImage(ConsumerInfo info) {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation != IDLE)
|
||||
return ret;
|
||||
if (info == null)
|
||||
Log.i("Fingerprint", "ConsumerInfo is null");
|
||||
ret = jniGetFingerprintImageEx(info);
|
||||
if (ret == VCS_RESULT_OK)
|
||||
mOperation = GETPRINT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getUserList(VcsStringArray userList) {
|
||||
VcsInt retCode = new VcsInt();
|
||||
userList.strlist = jniGetUserList(retCode);
|
||||
if (userList.strlist == null)
|
||||
return retCode.num;
|
||||
return VCS_RESULT_OK;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
if (mOperation != IDLE) {
|
||||
Log.e("Fingerprint", "Other operation is in progress, cancelling request");
|
||||
return null;
|
||||
}
|
||||
return jniGetVersion();
|
||||
}
|
||||
|
||||
public int identify(String userId) {
|
||||
int ret = VCS_RESULT_FAILED;
|
||||
if (mOperation == IDENTIFY)
|
||||
return VCS_RESULT_ALREADY_INPROGRESS;
|
||||
if (mOperation != IDLE) {
|
||||
return ret;
|
||||
} else {
|
||||
if (null == userId)
|
||||
userId = "";
|
||||
ret = jniIdentify(userId);
|
||||
if (ret == VCS_RESULT_OK)
|
||||
mOperation = IDENTIFY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int protect(byte toProtect[], VcsAddInfo addInfo, VcsByteArray protectedData) {
|
||||
if (toProtect == null || addInfo == null || protectedData == null)
|
||||
return VCS_RESULT_INVALID_ARGUMENT;
|
||||
return jniProtect(toProtect, addInfo, protectedData);
|
||||
}
|
||||
|
||||
public int registerListener(EventListener listener) {
|
||||
if (mOperation != IDLE)
|
||||
return VCS_RESULT_FAILED;
|
||||
mEventListener = listener;
|
||||
return VCS_RESULT_OK;
|
||||
}
|
||||
|
||||
public int setDetectFinger(int timeout) {
|
||||
return jniSetDetectFinger(timeout);
|
||||
}
|
||||
|
||||
public int setSecurityLevel(int level) {
|
||||
if (mOperation != IDLE)
|
||||
return VCS_RESULT_FAILED;
|
||||
if (level == VCS_SECURITY_LEVEL_LOW || level == VCS_SECURITY_LEVEL_REGULAR ||
|
||||
level == VCS_SECURITY_LEVEL_HIGH || level == VCS_SECURITY_LEVEL_VERY_HIGH)
|
||||
return jniSetSecurityLevel(level);
|
||||
return VCS_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
public int unProtect(byte protectedData[], VcsAddInfo addInfo, VcsByteArray unProtectedData) {
|
||||
if (protectedData == null || unProtectedData == null)
|
||||
return VCS_RESULT_INVALID_ARGUMENT;
|
||||
if (null == addInfo)
|
||||
addInfo = new VcsAddInfo();
|
||||
return jniUnprotect(protectedData, addInfo, unProtectedData);
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class FingerprintEvent {
|
||||
public Object eventData;
|
||||
public int eventId;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class IdentifyResult {
|
||||
public byte templateId[] = new byte[16];
|
||||
public int matchedFingerIndexes[] = new int[20];
|
||||
public int corrMinuCount[] = new int[4];
|
||||
public int vMinuCount[] = new int[4];
|
||||
public String appData;
|
||||
public int fMinuCount;
|
||||
public int fingerIndex;
|
||||
public float matchRate;
|
||||
public int matchScore;
|
||||
public int templateUpdated;
|
||||
public String userId;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class RemoveEnroll {
|
||||
public int fingerIndex;
|
||||
public String userId;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class SensorInfo {
|
||||
public int flexId;
|
||||
public String fwVersion;
|
||||
public int productId;
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class VLog {
|
||||
private static final String TAG = "ValidityService";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public static void i(final String message) {
|
||||
Log.i(TAG, message);
|
||||
}
|
||||
|
||||
public static void d(final String message) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void v(final String message) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void e(final String message, final Throwable t) {
|
||||
Log.e(TAG, message, t);
|
||||
}
|
||||
|
||||
public static void e(final String message) {
|
||||
Log.e(TAG, message);
|
||||
}
|
||||
|
||||
public static void w(final String message, final Throwable t) {
|
||||
Log.w(TAG, message, t);
|
||||
}
|
||||
|
||||
public static void w(final String message) {
|
||||
Log.w(TAG, message);
|
||||
}
|
||||
}
|
|
@ -1,390 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.LocalServerSocket;
|
||||
import android.net.LocalSocket;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
public class ValidityService extends Service implements FingerprintCore.EventListener {
|
||||
public static final String SOCKET_NAME = "validityservice";
|
||||
public static final String SOCKET_NAME_CB = "validityservice_callback";
|
||||
private LocalServerSocket mServerSocket = null;
|
||||
private LocalServerSocket mServerSocketCB = null;
|
||||
private LocalSocket mSocketCB = null;
|
||||
|
||||
public static final int CALL_BASE = 0;
|
||||
|
||||
public static final int CALL_INITSERVICE = CALL_BASE + 1;
|
||||
public static final int CALL_ENROLL = CALL_BASE + 2; // userId ,fingerIndex
|
||||
public static final int CALL_CANCEL = CALL_BASE + 3;
|
||||
public static final int CALL_REMOVE = CALL_BASE + 4; // userId ,fingerIndex
|
||||
public static final int CALL_IDENTIFY = CALL_BASE + 5; // userId
|
||||
public static final int CALL_GET_ENROLLED_FINGER_LIST = CALL_BASE + 6; // userId
|
||||
public static final int CALL_CLEANUP = CALL_BASE + 7;
|
||||
|
||||
public static final int CB_ERROR = 1;
|
||||
public static final int CB_ENROLL = 2;
|
||||
public static final int CB_REMOVED = 3;
|
||||
public static final int CB_ACQUIRED = 4;
|
||||
public static final int CB_AUTHENTICATED = 5;
|
||||
|
||||
private boolean mIsIdentify = false;
|
||||
private int mLastEnrollFingerindex = 0;
|
||||
private IdentifyResult mIdresult = null;
|
||||
private boolean mEnrollBad = false;
|
||||
private int mEnrollRepeatCount = 0;
|
||||
private int mActiveGid = 0;
|
||||
private boolean mIsNeedIdentify = false;
|
||||
private int mIdentifyImage = 0;
|
||||
|
||||
Fingerprint fp = new Fingerprint(this, this);
|
||||
|
||||
/** We should set a password after we enroll one finger. This password is "123456q"
|
||||
* The password hash method is SHA-1.
|
||||
*/
|
||||
public static final byte[] pwdhash = "bfff2dd4f1b310eb0dbf593bd83f94dd8d34077e".getBytes();
|
||||
|
||||
public int initService() {
|
||||
int ret = fp.getSensorStatus();
|
||||
VLog.i("init: ret=" + ret);
|
||||
VLog.i("init: version=" + fp.getVersion());
|
||||
notify_start();
|
||||
if (ret != 0 && ret != 1004) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void notify_start() {
|
||||
fp.cancel();
|
||||
fp.notify(Fingerprint.VCS_NOTIFY_ENROLL_BEGIN, null);
|
||||
}
|
||||
|
||||
public void notify_end() {
|
||||
fp.cancel();
|
||||
fp.notify(Fingerprint.VCS_NOTIFY_ENROLL_END, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
VLog.v("onCreate");
|
||||
try {
|
||||
mServerSocket = new LocalServerSocket(SOCKET_NAME);
|
||||
mServerSocketCB = new LocalServerSocket(SOCKET_NAME_CB);
|
||||
} catch (IOException e) {
|
||||
VLog.v("in onCreate, making server socket: " + e);
|
||||
return;
|
||||
}
|
||||
Thread t_server = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
LocalSocket socket = null;
|
||||
while (true) {
|
||||
try {
|
||||
VLog.v("Waiting for connection...");
|
||||
socket = mServerSocket.accept();
|
||||
VLog.v(".....Got socket: " + socket);
|
||||
if (socket != null) {
|
||||
startService(socket);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
VLog.v("in accept: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread t_server_cb = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
VLog.v("Waiting for connection...");
|
||||
mSocketCB = mServerSocketCB.accept();
|
||||
VLog.v(".....Got socket: " + mSocketCB);
|
||||
if (mSocketCB == null) {
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
VLog.v("in accept: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
t_server.start();
|
||||
t_server_cb.start();
|
||||
|
||||
ScreenReceiver receiver = new ScreenReceiver();
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_SCREEN_ON);
|
||||
filter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
registerReceiver(receiver, filter);
|
||||
}
|
||||
|
||||
private void startService(final LocalSocket socket) {
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
InputStream is = socket.getInputStream();
|
||||
OutputStream os = socket.getOutputStream();
|
||||
InputStreamReader isr = new InputStreamReader(is);
|
||||
OutputStreamWriter osr = new OutputStreamWriter(os);
|
||||
while (true) {
|
||||
byte[] data = new byte[128];
|
||||
int count = is.read(data);
|
||||
int ret = -1;
|
||||
String userId;
|
||||
int fingerIndex;
|
||||
for (int i = 0;i < count;i++){
|
||||
VLog.d("data["+i+"]="+data[i]);
|
||||
}
|
||||
switch (data[0]) {
|
||||
case CALL_INITSERVICE:
|
||||
ret = initService();
|
||||
break;
|
||||
case CALL_ENROLL:
|
||||
userId = "User_" + data[1];
|
||||
fingerIndex = data[2];
|
||||
mLastEnrollFingerindex = fingerIndex;
|
||||
mEnrollBad = false;
|
||||
mEnrollRepeatCount = 8;
|
||||
fp.verifyPassword(userId, pwdhash);
|
||||
ret = fp.enroll(userId, "", fingerIndex, Fingerprint.VCS_ENROLL_MODE_DEFAULT);
|
||||
break;
|
||||
case CALL_CANCEL:
|
||||
ret = fp.cancel();
|
||||
break;
|
||||
case CALL_REMOVE:
|
||||
userId = "User_" + data[1];
|
||||
fingerIndex = data[2];
|
||||
ret = fp.removeEnrolledFinger(userId, fingerIndex);
|
||||
if (fingerIndex == VcsEvents.FINGER_INDEX_ALL) {
|
||||
notify_end();
|
||||
notify_start();
|
||||
}
|
||||
break;
|
||||
case CALL_IDENTIFY:
|
||||
userId = "User_" + data[1];
|
||||
mIsIdentify = true;
|
||||
fp.setSecurityLevel(VcsEvents.VCS_SECURITY_LEVEL_HIGH);
|
||||
mIdresult = null;
|
||||
mActiveGid = data[1];
|
||||
ret = fp.identify(userId);
|
||||
break;
|
||||
case CALL_GET_ENROLLED_FINGER_LIST:
|
||||
userId = "User_" + data[1];
|
||||
VcsInt fingermask = new VcsInt();
|
||||
fp.getEnrolledFingerList(userId, fingermask);
|
||||
ret = fingermask.num;
|
||||
break;
|
||||
case CALL_CLEANUP:
|
||||
notify_end();
|
||||
ret = fp.cleanUp();
|
||||
break;
|
||||
default:
|
||||
VLog.e("unknown function:" + data[0]);
|
||||
}
|
||||
String str = ret + "";
|
||||
osr.write(str);
|
||||
osr.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
VLog.e("in startService loop: " + e.getMessage());
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException es) {
|
||||
VLog.e("Cannot close socket: " + es.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
|
||||
public int convertImageQuality(int imageQuality) {
|
||||
switch (imageQuality) {
|
||||
case VcsEvents.VCS_IMAGE_QUALITY_GOOD:
|
||||
return 0; // FINGERPRINT_ACQUIRED_GOOD
|
||||
case VcsEvents.VCS_IMAGE_QUALITY_REVERSE_MOTION:
|
||||
case VcsEvents.VCS_IMAGE_QUALITY_TOO_SHORT:
|
||||
case VcsEvents.VCS_IMAGE_QUALITY_WET_FINGER:
|
||||
return 1; // FINGERPRINT_ACQUIRED_PARTIAL
|
||||
case VcsEvents.VCS_IMAGE_QUALITY_STICTION:
|
||||
case VcsEvents.VCS_IMAGE_QUALITY_SOMETHING_ON_THE_SENSOR:
|
||||
return 3; // FINGERPRINT_ACQUIRED_IMAGER_DIRTY
|
||||
case VcsEvents.VCS_IMAGE_QUALITY_TOO_SLOW:
|
||||
return 4; // FINGERPRINT_ACQUIRED_TOO_SLOW
|
||||
case VcsEvents.VCS_IMAGE_QUALITY_TOO_FAST:
|
||||
return 5; // FINGERPRINT_ACQUIRED_TOO_FAST
|
||||
default:
|
||||
VLog.d("imageQuality="+imageQuality);
|
||||
return 2; // FINGERPRINT_ACQUIRED_INSUFFICIENT
|
||||
}
|
||||
}
|
||||
|
||||
/** Get which finger we detected. */
|
||||
public int getIdentifyFid() {
|
||||
if (mIdresult == null) return 1;
|
||||
return mIdresult.fingerIndex;
|
||||
}
|
||||
|
||||
public void onEvent(final FingerprintEvent event) {
|
||||
VLog.v("identify onEvent: receive event :" + event.eventId);
|
||||
OutputStreamWriter osr = null;
|
||||
try {
|
||||
OutputStream os = mSocketCB.getOutputStream();
|
||||
osr = new OutputStreamWriter(os);
|
||||
String str = null;
|
||||
switch (event.eventId) {
|
||||
case VcsEvents.VCS_EVT_EIV_FINGERPRINT_CAPTURE_REDUNDANT:
|
||||
str = CB_ACQUIRED + ":" + 1;
|
||||
mEnrollBad = true;
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_ENROLL_CAPTURE_STATUS:
|
||||
EnrollCaptureStatus data_status = (EnrollCaptureStatus)event.eventData;
|
||||
if (mEnrollBad) mEnrollBad = false;
|
||||
else mEnrollRepeatCount = mEnrollRepeatCount - 1;
|
||||
if (mEnrollRepeatCount != 0) {
|
||||
str = CB_ENROLL + ":" + mLastEnrollFingerindex + ":" + mEnrollRepeatCount;
|
||||
}
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_EIV_FINGERPRINT_CAPTURED_BAD:
|
||||
str = CB_ACQUIRED + ":" + convertImageQuality((int)event.eventData);
|
||||
mEnrollBad = true;
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_ENROLL_SUCCESS:
|
||||
str = CB_ENROLL + ":" + mLastEnrollFingerindex + ":" + 0;
|
||||
fp.setPassword("User_0", pwdhash);
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_ENROLL_FAILED:
|
||||
str = CB_ERROR + ":" + 2; //FINGERPRINT_ERROR_UNABLE_TO_PROCESS
|
||||
VLog.e("enroll onEvent: enroll error, result=" + (int)event.eventData);
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_VERIFY_COMPLETED:
|
||||
case VcsEvents.VCS_EVT_IDENTIFY_COMPLETED:
|
||||
mIdresult = (IdentifyResult)event.eventData;
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_EIV_FINGERPRINT_CAPTURED:
|
||||
FingerprintBitmap data_map = (FingerprintBitmap)event.eventData;
|
||||
mIdentifyImage = convertImageQuality(data_map.quality);
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_VERIFY_SUCCESS:
|
||||
case VcsEvents.VCS_EVT_IDENTIFY_SUCCESS:
|
||||
mIsIdentify = false;
|
||||
str = CB_AUTHENTICATED + ":" + getIdentifyFid();
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_SENSOR_REMOVED:
|
||||
mIsIdentify = false;
|
||||
str = CB_ERROR + ":" + 1; //FINGERPRINT_ERROR_HW_UNAVAILABLE
|
||||
VLog.e("identify onEvent: identify error, result=" + (int)event.eventData);
|
||||
break;
|
||||
case VcsEvents.VCS_EVT_VERIFY_FAILED:
|
||||
case VcsEvents.VCS_EVT_IDENTIFY_FAILED:
|
||||
mIsIdentify = false;
|
||||
VLog.e("identify onEvent: identify error, result=" + (int)event.eventData);
|
||||
switch ((int)event.eventData) {
|
||||
case VcsEvents.VCS_RESULT_BAD_QUALITY_IMAGE:
|
||||
str = CB_ACQUIRED + ":" + mIdentifyImage;
|
||||
case VcsEvents.VCS_RESULT_USER_DOESNT_EXIST:
|
||||
fp.setSecurityLevel(VcsEvents.VCS_SECURITY_LEVEL_HIGH);
|
||||
mIdresult = null;
|
||||
mIsIdentify = true;
|
||||
fp.identify("User_" + mActiveGid);
|
||||
if (str == null) {
|
||||
str = CB_ACQUIRED + ":" + 1; // FINGERPRINT_ACQUIRED_PARTIAL
|
||||
}
|
||||
break;
|
||||
case VcsEvents.VCS_RESULT_OPERATION_CANCELED:
|
||||
break;
|
||||
default:
|
||||
str = CB_ERROR + ":" + 2; //FINGERPRINT_ERROR_UNABLE_TO_PROCESS
|
||||
}
|
||||
break;
|
||||
default:
|
||||
VLog.v("identify onEvent: No need to process event :" + event.eventId);
|
||||
}
|
||||
if (str != null) {
|
||||
osr.write(str);
|
||||
osr.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
VLog.e("in onEvent: " + e.getMessage());
|
||||
try {
|
||||
osr.close();
|
||||
mSocketCB.close();
|
||||
} catch (IOException es) {
|
||||
VLog.e("Cannot close socket: " + es.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Our Keyguard will not call identify when turn on screen, so we need call it. */
|
||||
public void onScreenOn() {
|
||||
if (mIsNeedIdentify) {
|
||||
mIsNeedIdentify = false;
|
||||
fp.setSecurityLevel(VcsEvents.VCS_SECURITY_LEVEL_HIGH);
|
||||
mIdresult = null;
|
||||
mIsIdentify = true;
|
||||
fp.identify("User_" + mActiveGid);
|
||||
}
|
||||
}
|
||||
|
||||
public void onScreenOff() {
|
||||
if (mIsIdentify) {
|
||||
mIsNeedIdentify = true;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScreenReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
|
||||
onScreenOn();
|
||||
}
|
||||
else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
onScreenOff();
|
||||
}
|
||||
else VLog.e("Unknown intent:" + intent.getAction());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
public class ValidityServiceStarter extends Application {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
VLog.v("onCreate");
|
||||
Intent serviceintent = new Intent(this, ValidityService.class);
|
||||
startService(serviceintent);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class VcsAddInfo {
|
||||
public int algID;
|
||||
public byte data[];
|
||||
|
||||
public VcsAddInfo() {
|
||||
}
|
||||
|
||||
public VcsAddInfo(int algorithmID) {
|
||||
algID = algorithmID;
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class VcsByteArray {
|
||||
public byte data[];
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class VcsEvents {
|
||||
|
||||
public static final int FINGER_INDEX_LEFT_THUMB = 1;
|
||||
public static final int FINGER_INDEX_LEFT_INDEX = 2;
|
||||
public static final int FINGER_INDEX_LEFT_MIDDLE = 3;
|
||||
public static final int FINGER_INDEX_LEFT_RING = 4;
|
||||
public static final int FINGER_INDEX_LEFT_LITTLE = 5;
|
||||
public static final int FINGER_INDEX_RIGHT_THUMB = 6;
|
||||
public static final int FINGER_INDEX_RIGHT_INDEX = 7;
|
||||
public static final int FINGER_INDEX_RIGHT_MIDDLE = 8;
|
||||
public static final int FINGER_INDEX_RIGHT_RING = 9;
|
||||
public static final int FINGER_INDEX_RIGHT_LITTLE = 10;
|
||||
public static final int FINGER_INDEX_LEFT_THUMB_SECOND = 11;
|
||||
public static final int FINGER_INDEX_LEFT_INDEX_SECOND = 12;
|
||||
public static final int FINGER_INDEX_LEFT_MIDDLE_SECOND = 13;
|
||||
public static final int FINGER_INDEX_LEFT_RING_SECOND = 14;
|
||||
public static final int FINGER_INDEX_LEFT_LITTLE_SECOND = 15;
|
||||
public static final int FINGER_INDEX_RIGHT_THUMB_SECOND = 16;
|
||||
public static final int FINGER_INDEX_RIGHT_INDEX_SECOND = 17;
|
||||
public static final int FINGER_INDEX_RIGHT_MIDDLE_SECOND = 18;
|
||||
public static final int FINGER_INDEX_RIGHT_RING_SECOND = 19;
|
||||
public static final int FINGER_INDEX_RIGHT_LITTLE_SECOND = 20;
|
||||
public static final int FINGER_INDEX_ALL = 21;
|
||||
|
||||
public static final int VCS_EVT_SENSOR_REMOVED = 1;
|
||||
public static final int VCS_EVT_SENSOR_DETECTED = 2;
|
||||
public static final int VCS_EVT_SENSOR_READY_FOR_USE = 3;
|
||||
public static final int VCS_EVT_SENSOR_FAILED_INITIALIZATION = 4;
|
||||
public static final int VCS_EVT_SENSOR_FINGERPRINT_CAPTURE_COMPLETE = 5;
|
||||
public static final int VCS_EVT_SENSOR_RAW_FINGERPRINT_CAPTURE_COMPLETE = 6;
|
||||
public static final int VCS_EVT_SENSOR_FINGERPRINT_CAPTURE_FAILED = 7;
|
||||
public static final int VCS_EVT_SENSOR_FINGERPRINT_CAPTURE_START = 8;
|
||||
public static final int VCS_EVT_ALL_SENSORS_INITIALIZED = 9;
|
||||
public static final int VCS_EVT_SENSOR_FINGERPRINT_FAILED_SWIPE_RETRY = 10;
|
||||
public static final int VCS_EVT_FINGER_DETECTED = 11;
|
||||
public static final int VCS_EVT_ENROLL_COMPLETED = 13;
|
||||
public static final int VCS_EVT_VERIFY_COMPLETED = 14;
|
||||
public static final int VCS_EVT_IDENTIFY_COMPLETED = 15;
|
||||
public static final int VCS_EVT_ENROLL_NEXT_CAPTURE_START = 16;
|
||||
public static final int VCS_EVT_EIV_FINGERPRINT_CAPTURED = 17;
|
||||
public static final int VCS_EVT_FINGER_REMOVED = 20;
|
||||
public static final int VCS_EVT_ENROLL_CAPTURE_STATUS = 32;
|
||||
public static final int VCS_EVT_FINGER_SETTLED = 33;
|
||||
public static final int VCS_EVT_SET_IR_FLAGS = 37;
|
||||
public static final int VCS_EVT_SWIPE_DIRECTION = 41;
|
||||
public static final int VCS_EVT_SWIPE_SPEED_UPDATE = 42;
|
||||
public static final int VCS_EVT_EIV_FINGERPRINT_CAPTURED_BAD = 45;
|
||||
public static final int VCS_EVT_SENSOR_NON_RECOVERABLE = 46;
|
||||
public static final int VCS_EVT_ENVIRONMENT_NOISE_DETECTED = 47;
|
||||
public static final int VCS_EVT_EIV_FINGERPRINT_CAPTURE_REDUNDANT = 49;
|
||||
public static final int VCS_EVT_EIV_FINGERPRINT_CAPTURE_EARLY = 50;
|
||||
|
||||
public static final int VCS_EVT_ENROLL_SUCCESS = 421;
|
||||
public static final int VCS_EVT_VERIFY_SUCCESS = 422;
|
||||
public static final int VCS_EVT_IDENTIFY_SUCCESS = 423;
|
||||
public static final int VCS_EVT_ENROLL_FAILED = 424;
|
||||
public static final int VCS_EVT_VERIFY_FAILED = 425;
|
||||
public static final int VCS_EVT_IDENTIFY_FAILED = 426;
|
||||
public static final int VCS_EVT_GESTURE = 427;
|
||||
public static final int VCS_EVT_SENSOR_INFO = 428;
|
||||
|
||||
public static final int VCS_IMAGE_QUALITY_GOOD = 0;
|
||||
public static final int VCS_IMAGE_QUALITY_STICTION = 1;
|
||||
public static final int VCS_IMAGE_QUALITY_TOO_FAST = 2;
|
||||
public static final int VCS_IMAGE_QUALITY_TOO_SHORT = 4;
|
||||
public static final int VCS_IMAGE_QUALITY_REVERSE_MOTION = 8;
|
||||
public static final int VCS_IMAGE_QUALITY_TOO_SLOW = 16;
|
||||
public static final int VCS_IMAGE_QUALITY_SOMETHING_ON_THE_SENSOR = 512;
|
||||
public static final int VCS_IMAGE_QUALITY_ONE_HAND_SWIPE = 1024;
|
||||
public static final int VCS_IMAGE_QUALITY_FINGER_OFFSET = 4096;
|
||||
public static final int VCS_IMAGE_QUALITY_BAD_SWIPE = 8192;
|
||||
public static final int VCS_IMAGE_QUALITY_SKEW_TOO_LARGE = 32768;
|
||||
public static final int VCS_IMAGE_QUALITY_PRESSURE_TOO_LIGHT = 0x10000;
|
||||
public static final int VCS_IMAGE_QUALITY_FINGER_OFFSET_TOO_FAR_LEFT = 0x20000;
|
||||
public static final int VCS_IMAGE_QUALITY_FINGER_OFFSET_TOO_FAR_RIGHT = 0x40000;
|
||||
public static final int VCS_IMAGE_QUALITY_PRESSURE_TOO_HARD = 0x80000;
|
||||
public static final int VCS_IMAGE_QUALITY_ASP_DATA_INVALID = 0x100000;
|
||||
public static final int VCS_IMAGE_QUALITY_NOT_A_FINGER_SWIPE = 0x200000;
|
||||
public static final int VCS_IMAGE_QUALITY_BASELINE_DATA_INVALID = 0x400000;
|
||||
public static final int VCS_IMAGE_QUALITY_WET_FINGER = 0x1000000;
|
||||
public static final int VCS_IMAGE_QUALITY_FINGER_TOO_THIN = 0x2000000;
|
||||
public static final int VCS_IMAGE_QUALITY_PARTIAL_TOUCH = 0x8000000;
|
||||
public static final int VCS_IMAGE_QUALITY_EMPTY_TOUCH = 0x10000000;
|
||||
public static final int VCS_IMAGE_QUALITY_GESTURE = 0x20000000;
|
||||
public static final int VCS_IMAGE_QUALITY_PROCESS_FAILED = 0x40000000;
|
||||
public static final int VCS_IMAGE_QUALITY_PROCESS_FAILED_FATAL = 0x80000000;
|
||||
|
||||
public static final int VCS_NOTIFY_AUTH_SESSION_BEGIN = 5;
|
||||
public static final int VCS_NOTIFY_AUTH_SESSION_END = 6;
|
||||
|
||||
public static final int VCS_POLICY_AUTHENTICATE_ALWAYS = 1;
|
||||
public static final int VCS_POLICY_AUTHENTICATE_ON_SCREEN_UNLOCK_TIMEOUT = 2;
|
||||
public static final int VCS_POLICY_AUTHENTICATE_ON_PREVIOUS_IDENTIFY_TIMEOUT = 3;
|
||||
|
||||
public static final int VCS_PROTECT_ALG_SIMPLE_USER_DATA = 1;
|
||||
public static final int VCS_PROTECT_ALG_SIMPLE_APP_DATA = 2;
|
||||
|
||||
public static final int VCS_RESULT_FAILED = -1;
|
||||
public static final int VCS_RESULT_OK = 0;
|
||||
public static final int VCS_RESULT_CANCEL = 1;
|
||||
public static final int VCS_RESULT_OUT_OF_MEMORY = 2;
|
||||
public static final int VCS_RESULT_NO_MORE_ENTRIES = 3;
|
||||
public static final int VCS_RESULT_BAD_PARAM = 17;
|
||||
public static final int VCS_RESULT_SENSOR_NOT_FOUND = 19;
|
||||
public static final int VCS_RESULT_SENSOR_OPEN_FAILED = 22;
|
||||
public static final int VCS_RESULT_TIMEOUT = 34;
|
||||
public static final int VCS_RESULT_NULL_POINTER = 40;
|
||||
public static final int VCS_RESULT_SENSOR_BUSY = 46;
|
||||
public static final int VCS_RESULT_ERROR = 54;
|
||||
public static final int VCS_RESULT_TEMPLATE_FILE_CREATION_FAILED = 64;
|
||||
public static final int VCS_RESULT_USER_DOESNT_EXIST = 65;
|
||||
public static final int VCS_RESULT_TEMPLATE_DOESNT_EXIST = 66;
|
||||
public static final int VCS_RESULT_INVALID_USER_HANDLE = 70;
|
||||
public static final int VCS_RESULT_TEMPLATE_CORRUPTED = 87;
|
||||
public static final int VCS_RESULT_USER_FINGER_ALREADY_ENROLLED = 88;
|
||||
public static final int VCS_RESULT_USER_DATA_CORRUPTED = 91;
|
||||
public static final int VCS_RESULT_MATCHER_OPEN_FAILED = 300;
|
||||
public static final int VCS_RESULT_MATCHER_CLOSE_FAILED = 301;
|
||||
public static final int VCS_RESULT_MATCHER_MATCH_FAILED = 302;
|
||||
public static final int VCS_RESULT_MATCHER_EXTRACT_FAILED = 303;
|
||||
public static final int VCS_RESULT_MATCHER_ENROLL_FAILED = 304;
|
||||
public static final int VCS_RESULT_MATCHER_VERIFY_FAILED = 305;
|
||||
public static final int VCS_RESULT_MATCHER_ADD_IMAGE_FAILED = 306;
|
||||
public static final int VCS_RESULT_MATCHER_MATCH_IMAGE_FAILED = 307;
|
||||
public static final int VCS_RESULT_MATCHER_CHECK_QUALITY_FAILED = 308;
|
||||
public static final int VCS_RESULT_SERVICE_NOT_RUNNING = 321;
|
||||
public static final int VCS_RESULT_SENSOR_NOT_READY_FOR_USE = 358;
|
||||
public static final int VCS_RESULT_SENSOR_IS_REMOVED = 360;
|
||||
public static final int VCS_RESULT_OPERATION_CANCELED = 361;
|
||||
public static final int VCS_RESULT_USER_IDENTIFICATION_FAILED = 362;
|
||||
public static final int VCS_RESULT_USER_VERIFICATION_FAILED = 363;
|
||||
public static final int VCS_RESULT_MATCH_FAILED = 367;
|
||||
public static final int VCS_RESULT_SERVICE_STOPPED = 500;
|
||||
public static final int VCS_RESULT_GET_PRINT_STOPPED = 501;
|
||||
public static final int VCS_RESULT_OPERATION_DENIED = 510;
|
||||
public static final int VCS_RESULT_PIPE_ERROR = 511;
|
||||
public static final int VCS_RESULT_SENSOR_KEYS_NOT_READY = 512;
|
||||
public static final int VCS_RESULT_BAD_DEVICE = 513;
|
||||
public static final int VCS_RESULT_TOO_MANY_BAD_SWIPES = 515;
|
||||
public static final int VCS_RESULT_BAD_QUALITY_IMAGE = 601;
|
||||
public static final int VCS_RESULT_KEYDATA_NOT_FOUND = 777;
|
||||
public static final int VCS_RESULT_DATA_STORE_FAILED = 1001;
|
||||
public static final int VCS_RESULT_DATA_RETRIEVE_FAILED = 1002;
|
||||
public static final int VCS_RESULT_DATA_REMOVE_FAILED = 1003;
|
||||
public static final int VCS_RESULT_ALREADY_INPROGRESS = 1004;
|
||||
public static final int VCS_RESULT_NOT_IMPLEMENTED = 1005;
|
||||
public static final int VCS_RESULT_INVALID_ARGUMENT = 1006;
|
||||
|
||||
public static final int VCS_SECURITY_LEVEL_LOW = 0;
|
||||
public static final int VCS_SECURITY_LEVEL_REGULAR = 1;
|
||||
public static final int VCS_SECURITY_LEVEL_HIGH = 2;
|
||||
public static final int VCS_SECURITY_LEVEL_VERY_HIGH = 3;
|
||||
|
||||
public static final int VCS_SWIPE_DIRECTION_UP = 0;
|
||||
public static final int VCS_SWIPE_DIRECTION_DOWN = 1;
|
||||
public static final int VCS_SWIPE_DIRECTION_LEFT = 3;
|
||||
public static final int VCS_SWIPE_DIRECTION_RIGHT = 4;
|
||||
public static final int VCS_SWIPE_DIRECTION_REST = 5;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class VcsInt {
|
||||
public int num;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* Copyright (C) 2016 The Mokee Project
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.validity.fingerprint;
|
||||
|
||||
public class VcsStringArray {
|
||||
public String strlist[];
|
||||
}
|
Loading…
Reference in a new issue