blob: fab3bb920b50da5c082ee4235d9a545f53e10380 [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <poll.h>
#include <time.h>
#include <cstdint>
#include <base/logging.h>
#include <brillo/brillo_export.h>
#include "biod/fpc_biometrics_manager.h"
// The FPC sensor and biometric library requires platform-dependent functions to
// debug in the TEE environment and a timestamping method.
// PAL also requires the library user to provide I/O handlers.
#ifdef __cplusplus
extern "C" {
#endif
BRILLO_EXPORT void fp_pal_logprint(const char* log_message) {
LOG(ERROR) << log_message;
}
BRILLO_EXPORT void fp_pal_get_timestamp(uint64_t* time) {
#if defined(__x86_64__) || defined(__amd64__)
// We need to use RDTSC for SGX, clock_gettime() and friends aren't available.
uint64_t low, high;
__asm__ __volatile__("rdtsc" : "=a"(low), "=d"(high));
*time = (high << 32) | low;
#else
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
*time = now.tv_sec * 1000000L + now.tv_nsec / 1000;
#endif
}
static int get_fp_sensor_fd() {
return biod::FpcBiometricsManager::g_sensor_fd;
}
BRILLO_EXPORT int fp_pal_spi_writeread(uint8_t* access_buffer,
size_t access_buffer_size) {
int fd = get_fp_sensor_fd();
ssize_t ret = write(fd, access_buffer, access_buffer_size);
if (ret != access_buffer_size)
return -1;
ret = read(fd, access_buffer, access_buffer_size);
if (ret != access_buffer_size)
return -1;
return 0;
}
BRILLO_EXPORT int fp_pal_spi_write(uint8_t* access_buffer,
size_t access_buffer_size) {
return fp_pal_spi_writeread(access_buffer, access_buffer_size);
}
BRILLO_EXPORT int fp_pal_wait_for_sensor_interrupt(void) {
struct pollfd pfd;
pfd.fd = get_fp_sensor_fd();
if (pfd.fd < 0)
return -1;
pfd.events = POLLIN | POLLRDNORM;
pfd.revents = 0;
// TODO(b/37939568) libfp v0.8.0: fp_sensor_cancel() is not interrupting the
// syscall, force a timeout in the mean time to avoid blocking forever.
int ret = poll(&pfd, 1, biod::FpcBiometricsManager::kIRQTimeoutMs);
if (ret <= 0)
return -1;
if (!(pfd.revents & (POLLIN | POLLRDNORM)))
return -1;
return 0;
}
#ifdef __cplusplus
}
#endif