From d3936da2ade4960a6c341beac2f3899980d7d5b1 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Thu, 26 Aug 2021 19:16:12 +0100 Subject: [PATCH 01/57] feat: activation step implemented --- libfprint/drivers/goodixtls/goodix.c | 62 ++++++------ libfprint/drivers/goodixtls/goodix511.c | 123 +++++++++++++++++------- 2 files changed, 120 insertions(+), 65 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index c3596fc89..6349fdc18 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -17,6 +17,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include "fpi-usb-transfer.h" #define FP_COMPONENT "goodixtls" #include @@ -397,24 +398,26 @@ void goodix_receive_data(FpDevice *dev) { gboolean goodix_send_data(FpDevice *dev, guint8 *data, guint32 length, GDestroyNotify free_func, GError **error) { FpiDeviceGoodixTls *self = FPI_DEVICE_GOODIXTLS(dev); - FpiDeviceGoodixTlsClass *class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); - FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev); - - transfer->short_is_error = TRUE; + FpiDeviceGoodixTlsClass* class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); for (guint32 i = 0; i < length; i += GOODIX_EP_OUT_MAX_BUF_SIZE) { - fpi_usb_transfer_fill_bulk_full(transfer, class->ep_out, data + i, - GOODIX_EP_OUT_MAX_BUF_SIZE, NULL); - - if (!fpi_usb_transfer_submit_sync(transfer, GOODIX_TIMEOUT, error)) { - if (free_func) free_func(data); + FpiUsbTransfer* transfer = fpi_usb_transfer_new(dev); + transfer->short_is_error = TRUE; + + fpi_usb_transfer_fill_bulk_full(transfer, class->ep_out, data + i, + GOODIX_EP_OUT_MAX_BUF_SIZE, NULL); + + if (!fpi_usb_transfer_submit_sync(transfer, GOODIX_TIMEOUT, error)) { + if (free_func) + free_func(data); + fpi_usb_transfer_unref(transfer); + return FALSE; + } fpi_usb_transfer_unref(transfer); - return FALSE; - } } - if (free_func) free_func(data); - fpi_usb_transfer_unref(transfer); + if (free_func) + free_func(data); return TRUE; } @@ -494,26 +497,27 @@ void goodix_send_nop(FpDevice *dev, GoodixNoneCallback callback, goodix_receive_done(dev, NULL, 0, NULL); } -void goodix_send_mcu_get_image(FpDevice *dev, GoodixNoneCallback callback, - gpointer user_data) { - GoodixDefault payload = {.unused_flags = 0x01}; - GoodixCallbackInfo *cb_info; +void goodix_send_mcu_get_image(FpDevice* dev, GoodixNoneCallback callback, + gpointer user_data) +{ + GoodixDefault payload = {.unused_flags = 0x01}; + GoodixCallbackInfo* cb_info; - if (callback) { - cb_info = malloc(sizeof(GoodixCallbackInfo)); + if (callback) { + cb_info = malloc(sizeof(GoodixCallbackInfo)); - cb_info->callback = G_CALLBACK(callback); - cb_info->user_data = user_data; + cb_info->callback = G_CALLBACK(callback); + cb_info->user_data = user_data; - goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, (guint8 *)&payload, - sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, FALSE, - goodix_receive_none, cb_info); - return; - } + goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, (guint8*) &payload, + sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, FALSE, + goodix_receive_none, cb_info); + return; + } - goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, (guint8 *)&payload, - sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, FALSE, NULL, - NULL); + goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, (guint8*) &payload, + sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, FALSE, + NULL, NULL); } void goodix_send_mcu_switch_to_fdt_down(FpDevice *dev, guint8 *mode, diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 68af76f1e..a416516aa 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -17,6 +17,12 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include "fp-device.h" +#include "fp-image-device.h" +#include "fpi-assembling.h" +#include "fpi-image-device.h" +#include "fpi-ssm.h" +#include "gusb/gusb-device.h" #define FP_COMPONENT "goodixtls511" #include @@ -40,17 +46,16 @@ G_DEFINE_TYPE(FpiDeviceGoodixTls511, fpi_device_goodixtls511, // ---- ACTIVE SECTION START ---- enum activate_states { - ACTIVATE_READ_AND_NOP, - ACTIVATE_ENABLE_CHIP, - ACTIVATE_NOP, - ACTIVATE_CHECK_FW_VER, - ACTIVATE_CHECK_PSK, - ACTIVATE_RESET, - BREAK, - ACTIVATE_SET_MCU_IDLE, - ACTIVATE_SET_MCU_CONFIG, - ACTIVATE_SET_POWERDOWN_SCAN_FREQUENCY, - ACTIVATE_NUM_STATES, + ACTIVATE_READ_AND_NOP, + ACTIVATE_ENABLE_CHIP, + ACTIVATE_NOP, + ACTIVATE_CHECK_FW_VER, + ACTIVATE_CHECK_PSK, + ACTIVATE_RESET, + ACTIVATE_SET_MCU_IDLE, + ACTIVATE_SET_MCU_CONFIG, + ACTIVATE_SET_POWERDOWN_SCAN_FREQUENCY, + ACTIVATE_NUM_STATES, }; static void check_none(FpDevice *dev, gpointer user_data, GError *error) { @@ -150,7 +155,47 @@ static void check_preset_psk_read(FpDevice *dev, gboolean success, fpi_ssm_next_state(user_data); } - +static void check_idle(FpDevice* dev, gpointer user_data, GError* err) +{ + G_DEBUG_HERE(); + + if (err) { + fpi_ssm_mark_failed(user_data, err); + return; + } + fpi_ssm_next_state(user_data); +} +static void check_config_upload(FpDevice* dev, gboolean success, + gpointer user_data, GError* error) +{ + G_DEBUG_HERE(); + if (error) { + fpi_ssm_mark_failed(user_data, error); + } + else if (!success) { + GError* err = malloc(sizeof(GError)); + err->message = "Failed to upload config"; + fpi_ssm_mark_failed(user_data, err); + } + else { + fpi_ssm_next_state(user_data); + } +} +static void check_powerdown_scan_freq(FpDevice* dev, gboolean success, + gpointer user_data, GError* error) +{ + if (error) { + fpi_ssm_mark_failed(user_data, error); + } + else if (!success) { + GError* err = malloc(sizeof(GError)); + err->message = "Failed set powerdown"; + fpi_ssm_mark_failed(user_data, err); + } + else { + fpi_ssm_next_state(user_data); + } +} static void activate_run_state(FpiSsm *ssm, FpDevice *dev) { GError *error = NULL; @@ -183,33 +228,31 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev) { goodix_send_reset(dev, TRUE, 20, check_reset, ssm); break; - case BREAK: - g_set_error_literal(&error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Break"); - fpi_ssm_mark_failed(ssm, error); - break; - - // case ACTIVATE_SET_MCU_IDLE: - // goodix_send_mcu_switch_to_idle_mode(ssm, 20); - // break; - - // case ACTIVATE_SET_MCU_CONFIG: - // goodix_send_upload_config_mcu( - // ssm, goodix_511_config, sizeof(goodix_511_config), NULL, NULL, - // NULL); - // break; - - // case ACTIVATE_SET_POWERDOWN_SCAN_FREQUENCY: - // goodix_send_set_powerdown_scan_frequency(ssm, 100, NULL, NULL); - // break; - } + case ACTIVATE_SET_MCU_IDLE: + goodix_send_mcu_switch_to_idle_mode(dev, 20, check_idle, ssm); + break; + + case ACTIVATE_SET_MCU_CONFIG: + goodix_send_upload_config_mcu(dev, goodix_511_config, + sizeof(goodix_511_config), NULL, + check_config_upload, ssm); + break; + + case ACTIVATE_SET_POWERDOWN_SCAN_FREQUENCY: + goodix_send_set_powerdown_scan_frequency( + dev, 100, check_powerdown_scan_freq, ssm); + break; + } } static void activate_complete(FpiSsm *ssm, FpDevice *dev, GError *error) { - FpImageDevice *image_dev = FP_IMAGE_DEVICE(dev); + G_DEBUG_HERE(); + FpImageDevice* image_dev = FP_IMAGE_DEVICE(dev); - fpi_image_device_activate_complete(image_dev, error); + fpi_image_device_activate_complete(image_dev, error); - if (!error) goodix_tls(dev); + if (!error) + goodix_tls(dev); } // ---- ACTIVE SECTION END ---- @@ -249,8 +292,16 @@ static void dev_activate(FpImageDevice *img_dev) { activate_complete); } -static void dev_change_state(FpImageDevice *img_dev, - FpiImageDeviceState state) {} + + +static void dev_change_state(FpImageDevice* img_dev, FpiImageDeviceState state) +{ + FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(img_dev); + G_DEBUG_HERE(); + + if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON) { + } +} static void dev_deactivate(FpImageDevice *img_dev) { fpi_image_device_deactivate_complete(img_dev, NULL); From 06d4b299ce6d313774a738cf717100a3e02e5422 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Thu, 26 Aug 2021 21:02:38 +0100 Subject: [PATCH 02/57] chore: basics of tls server --- libfprint/drivers/goodixtls/goodixtls.c | 229 +++++++++++++----------- libfprint/drivers/goodixtls/goodixtls.h | 60 ++++++- 2 files changed, 175 insertions(+), 114 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 62118ac15..8b335717d 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -30,13 +30,10 @@ #include #include "drivers_api.h" +#include "fp-device.h" +#include "fpi-device.h" #include "goodixtls.h" -int sock; -FpiSsm *fpi_ssm; -pthread_t server; -SSL_CTX *ctx; - static unsigned int tls_server_psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk, @@ -51,63 +48,54 @@ static unsigned int tls_server_psk_server_callback(SSL *ssl, return sizeof(goodix_511_psk_0); } -int tls_server_create_socket(int port) { - int s; - struct sockaddr_in addr; - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) { - fp_dbg("Unable to create TLS server socket"); - fpi_ssm_mark_failed(fpi_ssm, fpi_device_error_new_msg( - FP_DEVICE_ERROR_GENERAL, - "Unable to create TLS server socket")); - return -1; - } +static int tls_server_create_socket(int port) +{ + int s; + struct sockaddr_in addr; - if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - fp_dbg("Unable to bind to TLS server socket"); - fpi_ssm_mark_failed(fpi_ssm, fpi_device_error_new_msg( - FP_DEVICE_ERROR_GENERAL, - "Unable to bind to TLS server socket")); - return -1; - } + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(INADDR_ANY); - if (listen(s, 1) < 0) { - fp_dbg("Unable to listen to TLS server socket"); - fpi_ssm_mark_failed(fpi_ssm, fpi_device_error_new_msg( - FP_DEVICE_ERROR_GENERAL, - "Unable to listen to TLS server socket")); - return -1; - } + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) { + return -1; + } + + if (bind(s, (struct sockaddr*) &addr, sizeof(addr)) < 0) { + return -1; + } + + if (listen(s, 1) < 0) { + return -1; + } - return s; + return s; } -SSL_CTX *tls_server_create_ctx(void) { - const SSL_METHOD *method; +static SSL_CTX* tls_server_create_ctx(void) +{ + const SSL_METHOD* method; - method = SSLv23_server_method(); + method = SSLv23_server_method(); - ctx = SSL_CTX_new(method); - if (!ctx) { - return NULL; - } + SSL_CTX* ctx = SSL_CTX_new(method); + if (!ctx) { + return NULL; + } - return ctx; + return ctx; } -void tls_server_config_ctx(void) { - SSL_CTX_set_ecdh_auto(ctx, 1); - SSL_CTX_set_dh_auto(ctx, 1); - SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); - SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); - SSL_CTX_set_cipher_list(ctx, "ALL"); +static void tls_server_config_ctx(SSL_CTX* ctx) +{ + SSL_CTX_set_ecdh_auto(ctx, 1); + SSL_CTX_set_dh_auto(ctx, 1); + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); + SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); + SSL_CTX_set_cipher_list(ctx, "ALL"); - SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); + SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); } void *tls_server_loop(void *arg) { @@ -142,71 +130,100 @@ void *tls_server_loop(void *arg) { } } -void tls_server_stop(void) { - close(sock); - SSL_CTX_free(ctx); -} - -void *tls_server_handshake_loop(void *arg) { - struct sockaddr_in addr; - guint len = sizeof(addr); - SSL *ssl; - - int client = accept(sock, (struct sockaddr *)&addr, &len); - if (client < 0) { - printf("%s\n", strerror(errno)); - fp_dbg("TLS server unable to accept socket request"); - } else { - ssl = SSL_new(ctx); - SSL_set_fd(ssl, client); +static gboolean goodix_tls_connect(GoodixTlsServer* self) +{ + struct sockaddr_in addr; + guint len = sizeof(addr); - if (SSL_accept(ssl) <= 0) { - printf("%s\n", strerror(errno)); - fp_dbg("TLS server unable to accept handshake request"); + int client_fd = accept(self->sock_fd, (struct sockaddr*) &addr, &len); + if (client_fd >= 0) { } - } - return 0; + + GError err; + err.code = errno; + err.message = strerror(errno); + self->connection_callback(self, &err); + return FALSE; +} +static void goodix_tls_send_handshake(GoodixTlsServer* self) +{ + const char reply[] = "Hello Goodix\n"; + SSL_write(self->ssl_layer, reply, strlen(reply)); } -void tls_server_handshake_init(void) { - int err = pthread_create(&server, NULL, &tls_server_handshake_loop, NULL); - if (err != 0) { - fp_dbg("Unable to create TLS server thread"); - fpi_ssm_mark_failed(fpi_ssm, fpi_device_error_new_msg( - FP_DEVICE_ERROR_GENERAL, - "Unable to create TLS server thread")); - } else { - fp_dbg("TLS server thread created"); - fpi_ssm_next_state(fpi_ssm); - } +void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, guint16 length) +{ + SSL_write(self->ssl_layer, data, length * sizeof(guint8)); +} +void goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, + guint16 length) +{ + SSL_read(self->serve_ssl, data, length * sizeof(guint8)); } -void tls_server_init(FpiSsm *ssm) { - fpi_ssm = ssm; +static void* goodix_tls_init_cli(void* me) +{ + GoodixTlsServer* self = me; + self->ssl_layer = SSL_new(self->ssl_ctx); + SSL_set_fd(self->ssl_layer, self->client_fd); + if (SSL_connect(self->ssl_layer) > 0) { + self->connection_callback(self, NULL); + } + else { + printf("failed to connect: %s", strerror(errno)); + } + return NULL; +} +static void* goodix_tls_init_serve(void* me) +{ + GoodixTlsServer* self = me; + self->serve_ssl = SSL_new(self->ssl_ctx); + SSL_set_fd(self->serve_ssl, self->sock_fd); + if (SSL_accept(self->serve_ssl) != 0) { + printf("failed to accept: %s", strerror(errno)); + } + return NULL; +} - SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); +gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error) +{ + SSL_shutdown(self->ssl_layer); + SSL_free(self->ssl_layer); - ctx = tls_server_create_ctx(); + SSL_shutdown(self->serve_ssl); + SSL_free(self->serve_ssl); - if (ctx == NULL) { - fp_dbg("Unable to create TLS server context"); - fpi_ssm_mark_failed( - ssm, fpi_device_error_new_msg(FP_DEVICE_ERROR_GENERAL, - "Unable to create TLS server context")); - return; - } + close(self->client_fd); + close(self->sock_fd); - tls_server_config_ctx(); + SSL_CTX_free(self->ssl_ctx); - sock = tls_server_create_socket(GOODIX_TLS_SERVER_PORT); - if (sock == -1) { - fp_dbg("Unable to create TLS server socket"); - fpi_ssm_mark_failed( - ssm, fpi_device_error_new_msg(FP_DEVICE_ERROR_GENERAL, - "Unable to create TLS server context")); - return; - } + return TRUE; +} - fpi_ssm_next_state(ssm); +gboolean goodix_tls_server_init(GoodixTlsServer* self, guint8* psk, + gsize length, GError** error) +{ + g_assert(self->decoded_callback); + g_assert(self->connection_callback); + g_assert(self->send_callback); + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); + self->ssl_ctx = tls_server_create_ctx(); + + int socks[2] = {0, 0}; + socketpair(AF_INET, SOCK_STREAM, 0, socks); + self->sock_fd = socks[0]; + self->client_fd = socks[1]; + + if (self->ssl_ctx == NULL) { + fp_dbg("Unable to create TLS server context"); + *error = fpi_device_error_new_msg(FP_DEVICE_ERROR_GENERAL, "Unable to " + "create TLS " + "server " + "context"); + return FALSE; + } + pthread_create(&self->cli_thread, 0, goodix_tls_init_cli, self); + pthread_create(&self->serve_thread, 0, goodix_tls_init_serve, self); } diff --git a/libfprint/drivers/goodixtls/goodixtls.h b/libfprint/drivers/goodixtls/goodixtls.h index 25052381d..1fe1b1a8d 100644 --- a/libfprint/drivers/goodixtls/goodixtls.h +++ b/libfprint/drivers/goodixtls/goodixtls.h @@ -19,6 +19,10 @@ #pragma once +#include + +#include + #define GOODIX_TLS_SERVER_PORT 4433 static const guint8 goodix_511_psk_0[] = { @@ -26,18 +30,58 @@ static const guint8 goodix_511_psk_0[] = { 0x49, 0x55, 0xbd, 0x69, 0xa9, 0xa9, 0x86, 0x1d, 0x9e, 0x91, 0x1f, 0xa2, 0x49, 0x85, 0xb6, 0x77, 0xe8, 0xdb, 0xd7, 0x2d, 0x43}; -SSL_CTX *tls_server_create_ctx(void); +typedef void (*GoodixTlsServerSendCallback)(GoodixTlsServer* self, guint8* data, + guint16 length); + +typedef void (*GoodixTlsServerConnectionCallback)(GoodixTlsServer* self, + GError* error); + +typedef void (*GoodixTlsServerDecodedCallback)(GoodixTlsServer* self, + guint8* data, gsize length, + GError* error); + +enum goodix_tls_serve_state { + GOODIX_TLS_STATE_CONNECT, +}; +typedef struct _GoodixTlsServer { + // This callback should be called when a TLS packet must be send to the + // device + GoodixTlsServerSendCallback send_callback; -int tls_server_create_socket(int port); + // This callback should be called when the connection is established. The + // error should be NULL. It can also be called when the connection fail. In + // this case, the error should not be NULL. + GoodixTlsServerConnectionCallback connection_callback; -void tls_server_config_ctx(void); + // This callback should be called when a TLS packet is decoded. The error + // should be NULL. + // It can also be called when the server fail to decode a packet. In this + // case, the error should not be NULL. + GoodixTlsServerDecodedCallback decoded_callback; -__attribute__((__noreturn__)) void *tls_server_loop(void *arg); + // Put what you need here. + SSL_CTX* ssl_ctx; + int sock_fd; + SSL* ssl_layer; + SSL* serve_ssl; + int client_fd; + pthread_t cli_thread; + pthread_t serve_thread; +} GoodixTlsServer; -void tls_server_stop(void); +// This is called only once to init the TLS server. +// Return TRUE on success, FALSE otherwise and error should be set. +gboolean goodix_tls_server_init(GoodixTlsServer* self, guint8* psk, + gsize length, GError** error); -void *tls_server_handshake_loop(void *arg); +// This can be called multiple times. It is called when the device send a TLS +// packet. +void goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, + guint16 length); -void tls_server_handshake_init(void); +void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, + guint16 length); -void tls_server_init(FpiSsm *ssm); +// This is called only once to deinit the TLS server. +// Return TRUE on success, FALSE otherwise and error should be set. +gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error); From 11d59becc0ed34757e14b2e4a1698f3d4af5e13f Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Thu, 26 Aug 2021 21:26:54 +0100 Subject: [PATCH 03/57] fix: domain of sockets and compile --- libfprint/drivers/goodixtls/goodixtls.c | 51 ++++++------------------- libfprint/drivers/goodixtls/goodixtls.h | 17 ++++----- 2 files changed, 20 insertions(+), 48 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 8b335717d..7f63d58c9 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -98,38 +98,6 @@ static void tls_server_config_ctx(SSL_CTX* ctx) SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); } -void *tls_server_loop(void *arg) { - // Handle connections - while (1) { - struct sockaddr_in addr; - guint len = sizeof(addr); - SSL *ssl; - const char reply[] = "Hello Goodix\n"; - - int client = accept(sock, (struct sockaddr *)&addr, &len); - if (client < 0) { - printf("%s\n", strerror(errno)); - fp_dbg("TLS server unable to accept request"); - kill(getpid(), SIGKILL); - // exit(EXIT_FAILURE); - } - - ssl = SSL_new(ctx); - SSL_set_fd(ssl, client); - - if (SSL_accept(ssl) <= 0) { - ERR_print_errors_fp(stderr); - } else { - SSL_write(ssl, reply, strlen(reply)); - } - SSL_shutdown(ssl); - SSL_free(ssl); - close(client); - - kill(getpid(), SIGKILL); - } -} - static gboolean goodix_tls_connect(GoodixTlsServer* self) { struct sockaddr_in addr; @@ -166,11 +134,11 @@ static void* goodix_tls_init_cli(void* me) GoodixTlsServer* self = me; self->ssl_layer = SSL_new(self->ssl_ctx); SSL_set_fd(self->ssl_layer, self->client_fd); - if (SSL_connect(self->ssl_layer) > 0) { + if (SSL_connect(self->ssl_layer) == 0) { self->connection_callback(self, NULL); } else { - printf("failed to connect: %s", strerror(errno)); + printf("failed to connect: %s\n", strerror(errno)); } return NULL; } @@ -180,7 +148,7 @@ static void* goodix_tls_init_serve(void* me) self->serve_ssl = SSL_new(self->ssl_ctx); SSL_set_fd(self->serve_ssl, self->sock_fd); if (SSL_accept(self->serve_ssl) != 0) { - printf("failed to accept: %s", strerror(errno)); + printf("failed to accept: %s\n", strerror(errno)); } return NULL; } @@ -204,20 +172,24 @@ gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error) gboolean goodix_tls_server_init(GoodixTlsServer* self, guint8* psk, gsize length, GError** error) { - g_assert(self->decoded_callback); + // g_assert(self->decoded_callback); g_assert(self->connection_callback); - g_assert(self->send_callback); + // g_assert(self->send_callback); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); self->ssl_ctx = tls_server_create_ctx(); int socks[2] = {0, 0}; - socketpair(AF_INET, SOCK_STREAM, 0, socks); + if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) != 0) { + g_set_error(error, G_FILE_ERROR, errno, + "failed to create socket pair: %s", strerror(errno)); + return FALSE; + } self->sock_fd = socks[0]; self->client_fd = socks[1]; if (self->ssl_ctx == NULL) { - fp_dbg("Unable to create TLS server context"); + fp_dbg("Unable to create TLS server context\n"); *error = fpi_device_error_new_msg(FP_DEVICE_ERROR_GENERAL, "Unable to " "create TLS " "server " @@ -226,4 +198,5 @@ gboolean goodix_tls_server_init(GoodixTlsServer* self, guint8* psk, } pthread_create(&self->cli_thread, 0, goodix_tls_init_cli, self); pthread_create(&self->serve_thread, 0, goodix_tls_init_serve, self); + return TRUE; } diff --git a/libfprint/drivers/goodixtls/goodixtls.h b/libfprint/drivers/goodixtls/goodixtls.h index 1fe1b1a8d..438ee8b49 100644 --- a/libfprint/drivers/goodixtls/goodixtls.h +++ b/libfprint/drivers/goodixtls/goodixtls.h @@ -30,23 +30,22 @@ static const guint8 goodix_511_psk_0[] = { 0x49, 0x55, 0xbd, 0x69, 0xa9, 0xa9, 0x86, 0x1d, 0x9e, 0x91, 0x1f, 0xa2, 0x49, 0x85, 0xb6, 0x77, 0xe8, 0xdb, 0xd7, 0x2d, 0x43}; -typedef void (*GoodixTlsServerSendCallback)(GoodixTlsServer* self, guint8* data, - guint16 length); +struct _GoodixTlsServer; -typedef void (*GoodixTlsServerConnectionCallback)(GoodixTlsServer* self, +typedef void (*GoodixTlsServerSendCallback)(struct _GoodixTlsServer* self, + guint8* data, guint16 length); + +typedef void (*GoodixTlsServerConnectionCallback)(struct _GoodixTlsServer* self, GError* error); -typedef void (*GoodixTlsServerDecodedCallback)(GoodixTlsServer* self, +typedef void (*GoodixTlsServerDecodedCallback)(struct _GoodixTlsServer* self, guint8* data, gsize length, GError* error); -enum goodix_tls_serve_state { - GOODIX_TLS_STATE_CONNECT, -}; typedef struct _GoodixTlsServer { // This callback should be called when a TLS packet must be send to the // device - GoodixTlsServerSendCallback send_callback; + // GoodixTlsServerSendCallback send_callback; // This callback should be called when the connection is established. The // error should be NULL. It can also be called when the connection fail. In @@ -57,7 +56,7 @@ typedef struct _GoodixTlsServer { // should be NULL. // It can also be called when the server fail to decode a packet. In this // case, the error should not be NULL. - GoodixTlsServerDecodedCallback decoded_callback; + // GoodixTlsServerDecodedCallback decoded_callback; // Put what you need here. SSL_CTX* ssl_ctx; From 14a78dbaa0e24b10941e199a337d76f009405095 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Wed, 1 Sep 2021 18:59:48 +0100 Subject: [PATCH 04/57] save --- libfprint/drivers/goodixtls/goodix.c | 180 +++++++++++++++++------- libfprint/drivers/goodixtls/goodix.h | 4 +- libfprint/drivers/goodixtls/goodix511.c | 14 +- libfprint/drivers/goodixtls/goodixtls.c | 136 ++++++++++++++---- libfprint/drivers/goodixtls/goodixtls.h | 19 ++- 5 files changed, 263 insertions(+), 90 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 6349fdc18..a68405e36 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -34,22 +34,20 @@ #include "goodixtls.h" typedef struct { - pthread_t tls_server_thread; - gint tls_server_sock; - SSL_CTX *tls_server_ctx; + GoodixTlsServer* tls_hop; - GSource *timeout; + GSource* timeout; - guint8 cmd; + guint8 cmd; - gboolean ack; - gboolean reply; + gboolean ack; + gboolean reply; - GoodixCmdCallback callback; - gpointer user_data; + GoodixCmdCallback callback; + gpointer user_data; - guint8 *data; - guint32 length; + guint8* data; + guint32 length; } FpiDeviceGoodixTlsPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(FpiDeviceGoodixTls, fpi_device_goodixtls, @@ -270,8 +268,9 @@ void goodix_receive_ack(FpDevice *dev, guint8 *data, guint16 length, } if (!priv->reply) { - goodix_receive_done(dev, NULL, 0, NULL); - return; + G_DEBUG_HERE(); + goodix_receive_done(dev, NULL, 0, NULL); + return; } priv->ack = FALSE; @@ -293,8 +292,9 @@ void goodix_receive_protocol(FpDevice *dev, guint8 *data, guint32 length) { return; if (cmd == GOODIX_CMD_ACK) { - goodix_receive_ack(dev, payload, payload_len, NULL, NULL); - return; + fp_dbg("got ack"); + goodix_receive_ack(dev, payload, payload_len, NULL, NULL); + return; } if (priv->cmd != cmd) { @@ -332,13 +332,17 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { switch (flags) { case GOODIX_FLAGS_MSG_PROTOCOL: - goodix_receive_protocol(dev, payload, payload_len); - break; + fp_dbg("Got protocol msg"); + goodix_receive_protocol(dev, payload, payload_len); + break; case GOODIX_FLAGS_TLS: - // TLS message sending it to TLS server. - // TODO - break; + fp_dbg("Got TLS msg"); + goodix_receive_done(dev, data, length, NULL); + + // TLS message sending it to TLS server. + // TODO + break; default: fp_warn("Unknown flags: 0x%02x", flags); @@ -829,27 +833,29 @@ void goodix_send_query_mcu_state(FpDevice *dev, GoodixDefaultCallback callback, NULL); } -void goodix_send_request_tls_connection(FpDevice *dev, - GoodixNoneCallback callback, - gpointer user_data) { - GoodixNone payload = {}; - GoodixCallbackInfo *cb_info; +void goodix_send_request_tls_connection(FpDevice* dev, + GoodixDefaultCallback callback, + gpointer user_data) +{ + GoodixNone payload = {}; + GoodixCallbackInfo* cb_info; - if (callback) { - cb_info = malloc(sizeof(GoodixCallbackInfo)); + if (callback) { + cb_info = malloc(sizeof(GoodixCallbackInfo)); - cb_info->callback = G_CALLBACK(callback); - cb_info->user_data = user_data; + cb_info->callback = G_CALLBACK(callback); + cb_info->user_data = user_data; - goodix_send_protocol(dev, GOODIX_CMD_REQUEST_TLS_CONNECTION, - (guint8 *)&payload, sizeof(payload), NULL, TRUE, - GOODIX_TIMEOUT, FALSE, goodix_receive_none, cb_info); - return; - } + goodix_send_protocol(dev, GOODIX_CMD_REQUEST_TLS_CONNECTION, + (guint8*) &payload, sizeof(payload), NULL, TRUE, + GOODIX_TIMEOUT, TRUE, goodix_receive_default, + cb_info); + return; + } - goodix_send_protocol(dev, GOODIX_CMD_REQUEST_TLS_CONNECTION, - (guint8 *)&payload, sizeof(payload), NULL, TRUE, - GOODIX_TIMEOUT, FALSE, NULL, NULL); + goodix_send_protocol(dev, GOODIX_CMD_REQUEST_TLS_CONNECTION, + (guint8*) &payload, sizeof(payload), NULL, TRUE, + GOODIX_TIMEOUT, TRUE, NULL, NULL); } void goodix_send_tls_successfully_established(FpDevice *dev, @@ -980,16 +986,76 @@ enum tls_states { TLS_NUM_STATES, }; -void goodix_tls_run_state(FpiSsm *ssm, FpDevice *dev) { - switch (fpi_ssm_get_cur_state(ssm)) { - case TLS_SERVER_INIT: - tls_server_init(ssm); - break; +static void on_goodix_tls_server_ready(GoodixTlsServer* server, GError* err, + gpointer dev) +{ + if (err) { + fp_err("server ready failed: %s", err->message); + return; + } + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + guint8 buff[1024]; + int got = + goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff), &err); + if (got <= 0) { + fp_err("failed to read ssl stream: %s (code: %d)", err->message, + err->code); + return; + } + fp_dbg("GOT, len: %d, %s", got, data_to_str(buff, got)); + // guint8 buff[1024]; + // int qty = goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff)); + // goodix_send_data(FP_DEVICE(dev), buff, qty, NULL, &err); + // goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff)); + // goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); +} - case TLS_SERVER_HANDSHAKE_INIT: - tls_server_handshake_init(); - break; - } +static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, + guint16 length, gpointer user_data, + GError* error) +{ + if (error) { + fp_err("failed to get tls handshake: %s", error->message); + goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); + return; + } + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(user_data); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + GError* err = NULL; + /*if (!goodix_tls_init_cli(priv->tls_hop, &err)) { + fp_err("failed to init tls cli: %s", err->message); + goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); + return; + }*/ + fp_dbg("len: %d, d: %s", length, data_to_str(data, length)); + // goodix_send_tls_successfully_established(dev, NULL, NULL); + goodix_tls_client_send(priv->tls_hop, data, length); + goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); + /*guint8 buff[1024]; + goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); + int got = + goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff), &err); + if (got <= 0) { + fp_err("failed to read ssl stream: %s (code: %d)", err->message, + err->code); + return; + } + fp_dbg("GOT, len: %d, %s", got, data_to_str(buff, got));*/ +} + +static void goodix_tls_ready(GoodixTlsServer* server, GError* err, gpointer dev) +{ + if (err) { + fp_err("failed to init tls server: %s, code: %d", err->message, + err->code); + return; + } + fp_dbg("Inited tls server"); + goodix_send_request_tls_connection(FP_DEVICE(dev), + on_goodix_request_tls_connection, dev); } void goodix_tls_complete(FpiSsm *ssm, FpDevice *dev, GError *error) { @@ -997,8 +1063,26 @@ void goodix_tls_complete(FpiSsm *ssm, FpDevice *dev, GError *error) { } void goodix_tls(FpDevice *dev) { - fpi_ssm_start(fpi_ssm_new(dev, goodix_tls_run_state, TLS_NUM_STATES), - goodix_tls_complete); + fp_dbg("Starting up goodix tls server"); + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + g_assert(priv->tls_hop == NULL); + priv->tls_hop = malloc(sizeof(GoodixTlsServer)); + GoodixTlsServer* s = priv->tls_hop; + s->connection_callback = on_goodix_tls_server_ready; + s->user_data = self; + GError* err = NULL; + if (!goodix_tls_server_init(priv->tls_hop, &err)) { + fp_err("failed to init tls server, error: %s, code: %d", err->message, + err->code); + return; + } + /*if (!goodix_tls_init_cli(s, &err)) { + fp_err("failed to init client: %s, code: %d", err->message, err->code); + return; + }*/ + goodix_tls_ready(s, err, self); } // ---- TLS SECTION END ---- diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index 131e20258..0088ba2e6 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -192,8 +192,8 @@ void goodix_send_firmware_version(FpDevice *dev, void goodix_send_query_mcu_state(FpDevice *dev, GoodixDefaultCallback callback, gpointer user_data); -void goodix_send_request_tls_connection(FpDevice *dev, - GoodixNoneCallback callback, +void goodix_send_request_tls_connection(FpDevice* dev, + GoodixDefaultCallback callback, gpointer user_data); void goodix_send_tls_successfully_established(FpDevice *dev, diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index a416516aa..fa2514f27 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -201,11 +201,15 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev) { switch (fpi_ssm_get_cur_state(ssm)) { case ACTIVATE_READ_AND_NOP: - // Nop seems to clear the previous command buffer. But we are unable to - // do so. - goodix_receive_data(dev); - goodix_send_nop(dev, check_none, ssm); - break; + /* Uncomment below in case the successfully established bit didn't get + run and you get a timeout when trying to rerun */ + // goodix_send_tls_successfully_established(dev, NULL, NULL); + // exit(0); + // Nop seems to clear the previous command buffer. But we are unable + // to do so. + goodix_receive_data(dev); + goodix_send_nop(dev, check_none, ssm); + break; case ACTIVATE_ENABLE_CHIP: goodix_send_enable_chip(dev, TRUE, check_none, ssm); diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 7f63d58c9..18c14ddc4 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -32,8 +34,24 @@ #include "drivers_api.h" #include "fp-device.h" #include "fpi-device.h" +#include "glibconfig.h" #include "goodixtls.h" +static GError* err_from_ssl(int code) +{ + BIO* b = BIO_new(BIO_s_mem()); + ERR_print_errors(b); + char* buff; + size_t len = BIO_get_mem_data(b, &buff); + GError* err = malloc(sizeof(GError)); + err->code = code; + char* msg = malloc(len); + memcpy(msg, buff, len); + err->message = msg; + BIO_free(b); + return err; +} + static unsigned int tls_server_psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk, @@ -77,7 +95,7 @@ static SSL_CTX* tls_server_create_ctx(void) { const SSL_METHOD* method; - method = SSLv23_server_method(); + method = TLS_server_method(); SSL_CTX* ctx = SSL_CTX_new(method); if (!ctx) { @@ -86,16 +104,21 @@ static SSL_CTX* tls_server_create_ctx(void) return ctx; } +static SSL_CTX* tls_cli_create_ctx() +{ + const SSL_METHOD* method = TLS_client_method(); + SSL_CTX* ctx = SSL_CTX_new(method); + return ctx; +} static void tls_server_config_ctx(SSL_CTX* ctx) { SSL_CTX_set_ecdh_auto(ctx, 1); SSL_CTX_set_dh_auto(ctx, 1); - SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); - SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); - SSL_CTX_set_cipher_list(ctx, "ALL"); - - SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); + // SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); + // SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); + // SSL_CTX_set_cipher_list(ctx, "ALL"); + // SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); } static gboolean goodix_tls_connect(GoodixTlsServer* self) @@ -110,7 +133,7 @@ static gboolean goodix_tls_connect(GoodixTlsServer* self) GError err; err.code = errno; err.message = strerror(errno); - self->connection_callback(self, &err); + self->connection_callback(self, &err, self->user_data); return FALSE; } static void goodix_tls_send_handshake(GoodixTlsServer* self) @@ -121,34 +144,90 @@ static void goodix_tls_send_handshake(GoodixTlsServer* self) void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, guint16 length) { + fp_dbg("Sending data to goodix tls server"); SSL_write(self->ssl_layer, data, length * sizeof(guint8)); + // send(self->client_fd, data, length * sizeof(guint8), 0); } -void goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, - guint16 length) + +void goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length) { - SSL_read(self->serve_ssl, data, length * sizeof(guint8)); + write(self->client_fd, data, length * sizeof(guint8)); } -static void* goodix_tls_init_cli(void* me) +int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, + guint16 length, GError** error) { - GoodixTlsServer* self = me; - self->ssl_layer = SSL_new(self->ssl_ctx); - SSL_set_fd(self->ssl_layer, self->client_fd); - if (SSL_connect(self->ssl_layer) == 0) { - self->connection_callback(self, NULL); + fp_dbg("READ START"); + int retr = SSL_read(self->ssl_layer, data, length * sizeof(guint8)); + if (retr <= 0) { + *error = err_from_ssl(retr); } - else { - printf("failed to connect: %s\n", strerror(errno)); + fp_dbg("READ END"); + return retr; +} + +static void tls_config_ssl(SSL* ssl) +{ + SSL_set_min_proto_version(ssl, TLS1_2_VERSION); + SSL_set_max_proto_version(ssl, TLS1_2_VERSION); + SSL_set_psk_server_callback(ssl, tls_server_psk_server_callback); + SSL_set_cipher_list(ssl, "ADH-AES128-SHA:ADH-AES128-SHA256:ADH-AES256-" + "SHA256:@SECLEVEL=0"); +} + +gboolean goodix_tls_init_cli(GoodixTlsServer* self, GError** error) +{ + SSL_CTX* ctx = tls_cli_create_ctx(); + // tls_server_config_ctx(ctx); + SSL* ssl_layer = SSL_new(ctx); + tls_config_ssl(ssl_layer); + + int retr = SSL_set_fd(ssl_layer, self->client_fd); + + if (retr > 0) { + retr = SSL_connect(ssl_layer); } - return NULL; + + if (retr <= 0) { + *error = err_from_ssl(retr); + } + // SSL_free(ssl_layer); + // SSL_CTX_free(ctx); + + return retr <= 0 ? 0 : 1; } + static void* goodix_tls_init_serve(void* me) { GoodixTlsServer* self = me; - self->serve_ssl = SSL_new(self->ssl_ctx); - SSL_set_fd(self->serve_ssl, self->sock_fd); - if (SSL_accept(self->serve_ssl) != 0) { - printf("failed to accept: %s\n", strerror(errno)); + self->ssl_layer = SSL_new(self->ssl_ctx); + tls_config_ssl(self->ssl_layer); + SSL_set_fd(self->ssl_layer, self->sock_fd); + int retr = SSL_accept(self->ssl_layer); + if (retr <= 0) { + self->connection_callback( + self, err_from_ssl(SSL_get_error(self->ssl_layer, retr)), + self->user_data); + } + else { + g_assert(self->connection_callback); + const char* msg = "HELLO WORLD"; + // SSL_write(self->ssl_layer, msg, strlen(msg)); + + /*char buff[1024]; + int qty = SSL_read(self->ssl_layer, buff, sizeof(buff) - 1); + if (qty <= 0) { + self->connection_callback( + self, + g_error_new(G_FILE_ERROR, SSL_get_error(self->ssl_layer, qty), + ""), + self->user_data); + return NULL; + } + buff[qty] = 0;*/ + + // fp_dbg("Finished tls setup server side, got: %s (%d)", buff, qty); + self->connection_callback(self, NULL, self->user_data); } return NULL; } @@ -158,8 +237,8 @@ gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error) SSL_shutdown(self->ssl_layer); SSL_free(self->ssl_layer); - SSL_shutdown(self->serve_ssl); - SSL_free(self->serve_ssl); + // SSL_shutdown(self->ssl_layer); + // SSL_free(self->ssl_layer); close(self->client_fd); close(self->sock_fd); @@ -169,15 +248,16 @@ gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error) return TRUE; } -gboolean goodix_tls_server_init(GoodixTlsServer* self, guint8* psk, - gsize length, GError** error) +gboolean goodix_tls_server_init(GoodixTlsServer* self, GError** error) { // g_assert(self->decoded_callback); g_assert(self->connection_callback); // g_assert(self->send_callback); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); + SSL_library_init(); self->ssl_ctx = tls_server_create_ctx(); + tls_server_config_ctx(self->ssl_ctx); int socks[2] = {0, 0}; if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) != 0) { @@ -196,7 +276,7 @@ gboolean goodix_tls_server_init(GoodixTlsServer* self, guint8* psk, "context"); return FALSE; } - pthread_create(&self->cli_thread, 0, goodix_tls_init_cli, self); pthread_create(&self->serve_thread, 0, goodix_tls_init_serve, self); + // return return TRUE; } diff --git a/libfprint/drivers/goodixtls/goodixtls.h b/libfprint/drivers/goodixtls/goodixtls.h index 438ee8b49..fffb14cdc 100644 --- a/libfprint/drivers/goodixtls/goodixtls.h +++ b/libfprint/drivers/goodixtls/goodixtls.h @@ -36,7 +36,8 @@ typedef void (*GoodixTlsServerSendCallback)(struct _GoodixTlsServer* self, guint8* data, guint16 length); typedef void (*GoodixTlsServerConnectionCallback)(struct _GoodixTlsServer* self, - GError* error); + GError* error, + gpointer user_data); typedef void (*GoodixTlsServerDecodedCallback)(struct _GoodixTlsServer* self, guint8* data, gsize length, @@ -59,28 +60,32 @@ typedef struct _GoodixTlsServer { // GoodixTlsServerDecodedCallback decoded_callback; // Put what you need here. + gpointer user_data; // Passed to all callbacks SSL_CTX* ssl_ctx; int sock_fd; SSL* ssl_layer; - SSL* serve_ssl; + // SSL* cli_ssl_layer; int client_fd; - pthread_t cli_thread; pthread_t serve_thread; } GoodixTlsServer; // This is called only once to init the TLS server. // Return TRUE on success, FALSE otherwise and error should be set. -gboolean goodix_tls_server_init(GoodixTlsServer* self, guint8* psk, - gsize length, GError** error); +gboolean goodix_tls_server_init(GoodixTlsServer* self, GError** error); + +gboolean goodix_tls_init_cli(GoodixTlsServer* self, GError** err); // This can be called multiple times. It is called when the device send a TLS // packet. -void goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, - guint16 length); +int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, + guint16 length, GError** error); void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, guint16 length); +void goodix_tls_client_send(GoodixTlsServer* self, guint8* data, + guint16 length); + // This is called only once to deinit the TLS server. // Return TRUE on success, FALSE otherwise and error should be set. gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error); From d50897946ca9c9a81c36d09e4bea4b2ba6a3ce5f Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Thu, 2 Sep 2021 18:34:14 +0100 Subject: [PATCH 05/57] chore: initial tls handshake sort of working --- libfprint/drivers/goodixtls/goodix.c | 55 ++++++++++++++++++---- libfprint/drivers/goodixtls/goodix.h | 2 + libfprint/drivers/goodixtls/goodix_proto.c | 4 +- libfprint/drivers/goodixtls/goodixtls.c | 11 +++-- libfprint/drivers/goodixtls/goodixtls.h | 2 + 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index a68405e36..d08e3f6ad 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -286,10 +286,12 @@ void goodix_receive_protocol(FpDevice *dev, guint8 *data, guint32 length) { gboolean valid_checksum, valid_null_checksum; // TODO implement checksum. if (!goodix_decode_protocol(data, length, &cmd, &payload, &payload_len, - &valid_checksum, &valid_null_checksum)) - // Protocol is not full, we still need data. - // TODO implement protocol assembling. - return; + &valid_checksum, &valid_null_checksum)) { + fp_err("Incomplete, size: %d", length); + // Protocol is not full, we still need data. + // TODO implement protocol assembling. + return; + } if (cmd == GOODIX_CMD_ACK) { fp_dbg("got ack"); @@ -312,6 +314,35 @@ void goodix_receive_protocol(FpDevice *dev, guint8 *data, guint32 length) { goodix_receive_done(dev, payload, payload_len, NULL); } +static void goodix_receive_tls(FpDevice* dev, guint8* data, guint32 length) +{ + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + g_autofree guint8* payload = NULL; + guint16 payload_len; + gboolean valid_checksum; // TODO implement checksum. + guint8 flags; + + if (!goodix_decode_pack(data, length, &flags, &payload, &payload_len, + &valid_checksum)) { + fp_err("Incomplete, size tls: %d", length); + // Protocol is not full, we still need data. + // TODO implement protocol assembling. + return; + } + + if (!priv->reply) { + fp_warn("Didn't excpect a reply for command: 0x%02x", priv->cmd); + return; + } + + if (priv->ack) + fp_warn("Didn't got ACK for command: 0x%02x", priv->cmd); + + goodix_receive_done(dev, payload, payload_len, NULL); +} + void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { FpiDeviceGoodixTls *self = FPI_DEVICE_GOODIXTLS(dev); FpiDeviceGoodixTlsPrivate *priv = @@ -326,9 +357,10 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { priv->length += length; if (!goodix_decode_pack(priv->data, priv->length, &flags, &payload, - &payload_len, &valid_checksum)) - // Packet is not full, we still need data. - return; + &payload_len, &valid_checksum)) { + // Packet is not full, we still need data. + return; + } switch (flags) { case GOODIX_FLAGS_MSG_PROTOCOL: @@ -338,7 +370,9 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { case GOODIX_FLAGS_TLS: fp_dbg("Got TLS msg"); - goodix_receive_done(dev, data, length, NULL); + // goodix_receive_done(dev, data, length, NULL); + goodix_receive_done(dev, payload, payload_len, NULL); + // goodix_receive_tls(dev, payload, priv->length); // TLS message sending it to TLS server. // TODO @@ -997,6 +1031,7 @@ static void on_goodix_tls_server_ready(GoodixTlsServer* server, GError* err, FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); guint8 buff[1024]; + fp_dbg("TLS connection ready"); int got = goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff), &err); if (got <= 0) { @@ -1033,6 +1068,10 @@ static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, fp_dbg("len: %d, d: %s", length, data_to_str(data, length)); // goodix_send_tls_successfully_established(dev, NULL, NULL); goodix_tls_client_send(priv->tls_hop, data, length); + guint8 buff[1024]; + int size = goodix_tls_client_recv(priv->tls_hop, buff, sizeof(buff)); + goodix_send_pack(dev, GOODIX_FLAGS_TLS, buff, size, NULL, &err); + goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); /*guint8 buff[1024]; goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index 0088ba2e6..b1618a042 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -225,6 +225,8 @@ gboolean goodix_dev_deinit(FpDevice *dev, GError **error); // ---- TLS SECTION START ---- +void goodix_send_tls() + void goodix_tls_run_state(FpiSsm *ssm, FpDevice *dev); void goodix_tls_complete(FpiSsm *ssm, FpDevice *dev, GError *error); diff --git a/libfprint/drivers/goodixtls/goodix_proto.c b/libfprint/drivers/goodixtls/goodix_proto.c index 980f35990..0f61b5f46 100644 --- a/libfprint/drivers/goodixtls/goodix_proto.c +++ b/libfprint/drivers/goodixtls/goodix_proto.c @@ -19,6 +19,7 @@ #include #include +#include #include "goodix_proto.h" @@ -83,7 +84,8 @@ gboolean goodix_decode_pack(guint8 *data, guint32 data_len, guint8 *flags, if (data_len < sizeof(GoodixPack) + sizeof(guint8)) return FALSE; - length = GUINT16_FROM_LE(pack->length); + length = pack->length; // length = GUINT16_FROM_LE(pack->length); + printf("SIZE: %d\n", length); if (data_len < length + sizeof(GoodixPack) + sizeof(guint8)) return FALSE; diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 18c14ddc4..577b78691 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -115,10 +115,11 @@ static void tls_server_config_ctx(SSL_CTX* ctx) { SSL_CTX_set_ecdh_auto(ctx, 1); SSL_CTX_set_dh_auto(ctx, 1); + SSL_CTX_set_cipher_list(ctx, "ALL"); // SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); // SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); // SSL_CTX_set_cipher_list(ctx, "ALL"); - // SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); + SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); } static gboolean goodix_tls_connect(GoodixTlsServer* self) @@ -153,6 +154,9 @@ void goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length) { write(self->client_fd, data, length * sizeof(guint8)); } +int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length) { + return read(self->client_fd, data, length * sizeof(guint8)); +} int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, guint16 length, GError** error) @@ -171,8 +175,7 @@ static void tls_config_ssl(SSL* ssl) SSL_set_min_proto_version(ssl, TLS1_2_VERSION); SSL_set_max_proto_version(ssl, TLS1_2_VERSION); SSL_set_psk_server_callback(ssl, tls_server_psk_server_callback); - SSL_set_cipher_list(ssl, "ADH-AES128-SHA:ADH-AES128-SHA256:ADH-AES256-" - "SHA256:@SECLEVEL=0"); + SSL_set_cipher_list(ssl, "ALL"); } gboolean goodix_tls_init_cli(GoodixTlsServer* self, GError** error) @@ -203,7 +206,9 @@ static void* goodix_tls_init_serve(void* me) self->ssl_layer = SSL_new(self->ssl_ctx); tls_config_ssl(self->ssl_layer); SSL_set_fd(self->ssl_layer, self->sock_fd); + fp_dbg("TLS server waiting to accept..."); int retr = SSL_accept(self->ssl_layer); + fp_dbg("TLS server accept done"); if (retr <= 0) { self->connection_callback( self, err_from_ssl(SSL_get_error(self->ssl_layer, retr)), diff --git a/libfprint/drivers/goodixtls/goodixtls.h b/libfprint/drivers/goodixtls/goodixtls.h index fffb14cdc..3dd8ef760 100644 --- a/libfprint/drivers/goodixtls/goodixtls.h +++ b/libfprint/drivers/goodixtls/goodixtls.h @@ -86,6 +86,8 @@ void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, void goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length); +int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length); + // This is called only once to deinit the TLS server. // Return TRUE on success, FALSE otherwise and error should be set. gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error); From 6149f923cc1e9efa05c5353ea2336461fd6e66d6 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Thu, 2 Sep 2021 20:22:28 +0100 Subject: [PATCH 06/57] chore: handshake working but decrypt error on final step --- libfprint/drivers/goodixtls/goodix.c | 92 ++++++++++++++++++++++--- libfprint/drivers/goodixtls/goodix.h | 6 +- libfprint/drivers/goodixtls/goodix511.c | 4 +- libfprint/drivers/goodixtls/goodixtls.c | 28 ++++---- libfprint/drivers/goodixtls/goodixtls.h | 1 + 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index d08e3f6ad..66769f319 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -1014,6 +1014,20 @@ gboolean goodix_dev_deinit(FpDevice *dev, GError **error) { // ---- TLS SECTION START ---- +void goodix_read_tls(FpDevice* dev, GoodixTlsCallback callback, + gpointer user_data) +{ + + fp_dbg("goodix_read_tls()"); + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + priv->callback = callback; + priv->user_data = user_data; + priv->reply = TRUE; + goodix_receive_data(FP_DEVICE(self)); +} + enum tls_states { TLS_SERVER_INIT, TLS_SERVER_HANDSHAKE_INIT, @@ -1030,22 +1044,74 @@ static void on_goodix_tls_server_ready(GoodixTlsServer* server, GError* err, FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); - guint8 buff[1024]; fp_dbg("TLS connection ready"); - int got = - goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff), &err); - if (got <= 0) { - fp_err("failed to read ssl stream: %s (code: %d)", err->message, - err->code); - return; - } - fp_dbg("GOT, len: %d, %s", got, data_to_str(buff, got)); // guint8 buff[1024]; // int qty = goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff)); // goodix_send_data(FP_DEVICE(dev), buff, qty, NULL, &err); // goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff)); // goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); } +typedef struct _goodix_tls_handshake_state { + int count; + void (*callback)(FpDevice*, GError*, struct _goodix_tls_handshake_state*); + FpDevice* dev; + +} goodix_tls_handshake_state; + +static void on_goodix_tls_read_handshake(FpDevice* dev, guint8* data, + guint16 length, gpointer user_data, + GError* error) +{ + goodix_tls_handshake_state* state = (goodix_tls_handshake_state*) user_data; + if (error) { + fp_err("failed to read tls during handshake: %s, code: %d", + error->message, error->code); + state->callback(dev, error, state); + return; + } + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(state->dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + fp_dbg("handshake loop, got: %s, size: %d", data_to_str(data, length), + length); + + goodix_tls_client_send(priv->tls_hop, data, length); + + if (state->count >= 2) { + fp_dbg("Reading to proxy back"); + guint8 buff[1024]; + int size = goodix_tls_client_recv(priv->tls_hop, buff, sizeof(buff)); + if (size < 0) { + fp_err("failed to recieve from server: %d", size); + + state->callback(dev, g_error_new(g_io_error_quark(), size, ""), + state); + return; + } + fp_dbg("got: %s from the server (size: %d)", data_to_str(buff, size), + size); + GError* err = NULL; + if (!goodix_send_data(dev, buff, size, NULL, &err)) { + fp_err("failed to send tls data back: %s, code: %d", err->message, + err->code); + state->callback(dev, err, state); + return; + } + state->callback(dev, NULL, state); + } + else { + ++state->count; + goodix_read_tls(dev, on_goodix_tls_read_handshake, state); + } +} +static void on_goodix_tls_handshake_done(FpDevice* dev, GError* err, + goodix_tls_handshake_state* state) +{ + fp_dbg("DONE"); + free(state); + + goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); +} static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, guint16 length, gpointer user_data, @@ -1072,7 +1138,13 @@ static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, int size = goodix_tls_client_recv(priv->tls_hop, buff, sizeof(buff)); goodix_send_pack(dev, GOODIX_FLAGS_TLS, buff, size, NULL, &err); - goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); + goodix_tls_handshake_state* hs_st = + malloc(sizeof(goodix_tls_handshake_state)); + hs_st->callback = on_goodix_tls_handshake_done; + hs_st->dev = dev; + hs_st->count = 0; + goodix_read_tls(dev, on_goodix_tls_read_handshake, hs_st); + /*guint8 buff[1024]; goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); int got = diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index b1618a042..04f57c0c1 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -65,6 +65,7 @@ typedef void (*GoodixNoneCallback)(FpDevice *dev, gpointer user_data, typedef void (*GoodixDefaultCallback)(FpDevice *dev, guint8 *data, guint16 length, gpointer user_data, GError *error); +typedef GoodixDefaultCallback GoodixTlsCallback; gchar *data_to_str(guint8 *data, guint32 length); @@ -225,9 +226,10 @@ gboolean goodix_dev_deinit(FpDevice *dev, GError **error); // ---- TLS SECTION START ---- -void goodix_send_tls() +void goodix_read_tls(FpDevice* dev, GoodixTlsCallback callback, + gpointer user_data); -void goodix_tls_run_state(FpiSsm *ssm, FpDevice *dev); +void goodix_tls_run_state(FpiSsm* ssm, FpDevice* dev); void goodix_tls_complete(FpiSsm *ssm, FpDevice *dev, GError *error); diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index fa2514f27..81ea66b1d 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -205,8 +205,8 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev) { run and you get a timeout when trying to rerun */ // goodix_send_tls_successfully_established(dev, NULL, NULL); // exit(0); - // Nop seems to clear the previous command buffer. But we are unable - // to do so. + // Nop seems to clear the previous command buffer. But we are + // unable to do so. goodix_receive_data(dev); goodix_send_nop(dev, check_none, ssm); break; diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 577b78691..430decc2a 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -37,18 +37,14 @@ #include "glibconfig.h" #include "goodixtls.h" -static GError* err_from_ssl(int code) +static GError* err_from_ssl() { - BIO* b = BIO_new(BIO_s_mem()); - ERR_print_errors(b); - char* buff; - size_t len = BIO_get_mem_data(b, &buff); GError* err = malloc(sizeof(GError)); + unsigned long code = ERR_get_error(); err->code = code; - char* msg = malloc(len); - memcpy(msg, buff, len); - err->message = msg; - BIO_free(b); + const char* msg = ERR_reason_error_string(code); + err->message = malloc(strlen(msg)); + strcpy(err->message, msg); return err; } @@ -60,6 +56,7 @@ static unsigned int tls_server_psk_server_callback(SSL *ssl, fp_dbg("Provided PSK R is too long for OpenSSL"); return 0; } + fp_dbg("PSK WANTED"); psk = (unsigned char *)&goodix_511_psk_0; @@ -116,8 +113,8 @@ static void tls_server_config_ctx(SSL_CTX* ctx) SSL_CTX_set_ecdh_auto(ctx, 1); SSL_CTX_set_dh_auto(ctx, 1); SSL_CTX_set_cipher_list(ctx, "ALL"); - // SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); - // SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); + SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); // SSL_CTX_set_cipher_list(ctx, "ALL"); SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); } @@ -164,7 +161,8 @@ int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, fp_dbg("READ START"); int retr = SSL_read(self->ssl_layer, data, length * sizeof(guint8)); if (retr <= 0) { - *error = err_from_ssl(retr); + g_set_error(error, g_io_channel_error_quark(), retr, + ""); // err_from_ssl(retr); } fp_dbg("READ END"); return retr; @@ -192,7 +190,7 @@ gboolean goodix_tls_init_cli(GoodixTlsServer* self, GError** error) } if (retr <= 0) { - *error = err_from_ssl(retr); + //*error = err_from_ssl(retr); } // SSL_free(ssl_layer); // SSL_CTX_free(ctx); @@ -210,9 +208,7 @@ static void* goodix_tls_init_serve(void* me) int retr = SSL_accept(self->ssl_layer); fp_dbg("TLS server accept done"); if (retr <= 0) { - self->connection_callback( - self, err_from_ssl(SSL_get_error(self->ssl_layer, retr)), - self->user_data); + self->connection_callback(self, err_from_ssl(), self->user_data); } else { g_assert(self->connection_callback); diff --git a/libfprint/drivers/goodixtls/goodixtls.h b/libfprint/drivers/goodixtls/goodixtls.h index 3dd8ef760..ff0160279 100644 --- a/libfprint/drivers/goodixtls/goodixtls.h +++ b/libfprint/drivers/goodixtls/goodixtls.h @@ -25,6 +25,7 @@ #define GOODIX_TLS_SERVER_PORT 4433 +// static const guint8 goodix_511_psk_0[64] = {0}; static const guint8 goodix_511_psk_0[] = { 0xba, 0x1a, 0x86, 0x03, 0x7c, 0x1d, 0x3c, 0x71, 0xc3, 0xaf, 0x34, 0x49, 0x55, 0xbd, 0x69, 0xa9, 0xa9, 0x86, 0x1d, 0x9e, 0x91, 0x1f, From f1a9647d5681e2953e21e5bf0ae33259c0ed1b67 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Thu, 2 Sep 2021 21:21:11 +0100 Subject: [PATCH 07/57] feat: tls handshaking done --- libfprint/drivers/goodixtls/goodix.c | 8 +++++++- libfprint/drivers/goodixtls/goodixtls.c | 23 +++++++++++++++-------- libfprint/drivers/goodixtls/goodixtls.h | 3 +-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 66769f319..8c84d49f4 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -1075,7 +1075,8 @@ static void on_goodix_tls_read_handshake(FpDevice* dev, guint8* data, fp_dbg("handshake loop, got: %s, size: %d", data_to_str(data, length), length); - goodix_tls_client_send(priv->tls_hop, data, length); + int sent = goodix_tls_client_send(priv->tls_hop, data, length); + fp_dbg("sent: %d bytes", sent); if (state->count >= 2) { fp_dbg("Reading to proxy back"); @@ -1136,6 +1137,11 @@ static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, goodix_tls_client_send(priv->tls_hop, data, length); guint8 buff[1024]; int size = goodix_tls_client_recv(priv->tls_hop, buff, sizeof(buff)); + if (size < 0) { + fp_err("failed to read: %d", size); + goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); + return; + } goodix_send_pack(dev, GOODIX_FLAGS_TLS, buff, size, NULL, &err); goodix_tls_handshake_state* hs_st = diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 430decc2a..2750b1c82 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -35,6 +35,7 @@ #include "fp-device.h" #include "fpi-device.h" #include "glibconfig.h" +#include "goodix.h" #include "goodixtls.h" static GError* err_from_ssl() @@ -56,11 +57,17 @@ static unsigned int tls_server_psk_server_callback(SSL *ssl, fp_dbg("Provided PSK R is too long for OpenSSL"); return 0; } - fp_dbg("PSK WANTED"); - - psk = (unsigned char *)&goodix_511_psk_0; - - return sizeof(goodix_511_psk_0); + fp_dbg("PSK WANTED %d", max_psk_len); + // I don't know why we must use OPENSSL_hexstr2buf but just copying zeros + // doesn't work + const char* buff = "000000000000000000000000000000000000000000000000000000000" + "0000000"; + long len = 0; + unsigned char* key = OPENSSL_hexstr2buf(buff, &len); + memcpy(psk, key, len); + OPENSSL_free(key); + + return len; } static int tls_server_create_socket(int port) @@ -147,9 +154,9 @@ void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, guint16 length) // send(self->client_fd, data, length * sizeof(guint8), 0); } -void goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length) +int goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length) { - write(self->client_fd, data, length * sizeof(guint8)); + return write(self->client_fd, data, length * sizeof(guint8)); } int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length) { return read(self->client_fd, data, length * sizeof(guint8)); @@ -278,6 +285,6 @@ gboolean goodix_tls_server_init(GoodixTlsServer* self, GError** error) return FALSE; } pthread_create(&self->serve_thread, 0, goodix_tls_init_serve, self); - // return + return TRUE; } diff --git a/libfprint/drivers/goodixtls/goodixtls.h b/libfprint/drivers/goodixtls/goodixtls.h index ff0160279..16167afbc 100644 --- a/libfprint/drivers/goodixtls/goodixtls.h +++ b/libfprint/drivers/goodixtls/goodixtls.h @@ -84,8 +84,7 @@ int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, guint16 length); -void goodix_tls_client_send(GoodixTlsServer* self, guint8* data, - guint16 length); +int goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length); int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length); From caf3657b6067f50c3800b3b651a42ff4f0805751 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Thu, 2 Sep 2021 21:23:32 +0100 Subject: [PATCH 08/57] chore: cleanup --- libfprint/drivers/goodixtls/goodix.c | 31 +------ libfprint/drivers/goodixtls/goodixtls.c | 104 ------------------------ libfprint/drivers/goodixtls/goodixtls.h | 3 - 3 files changed, 2 insertions(+), 136 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 8c84d49f4..6ae695a33 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -370,9 +370,7 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { case GOODIX_FLAGS_TLS: fp_dbg("Got TLS msg"); - // goodix_receive_done(dev, data, length, NULL); goodix_receive_done(dev, payload, payload_len, NULL); - // goodix_receive_tls(dev, payload, priv->length); // TLS message sending it to TLS server. // TODO @@ -1045,11 +1043,6 @@ static void on_goodix_tls_server_ready(GoodixTlsServer* server, GError* err, FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); fp_dbg("TLS connection ready"); - // guint8 buff[1024]; - // int qty = goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff)); - // goodix_send_data(FP_DEVICE(dev), buff, qty, NULL, &err); - // goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff)); - // goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); } typedef struct _goodix_tls_handshake_state { int count; @@ -1127,13 +1120,8 @@ static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); GError* err = NULL; - /*if (!goodix_tls_init_cli(priv->tls_hop, &err)) { - fp_err("failed to init tls cli: %s", err->message); - goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); - return; - }*/ + fp_dbg("len: %d, d: %s", length, data_to_str(data, length)); - // goodix_send_tls_successfully_established(dev, NULL, NULL); goodix_tls_client_send(priv->tls_hop, data, length); guint8 buff[1024]; int size = goodix_tls_client_recv(priv->tls_hop, buff, sizeof(buff)); @@ -1150,17 +1138,6 @@ static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, hs_st->dev = dev; hs_st->count = 0; goodix_read_tls(dev, on_goodix_tls_read_handshake, hs_st); - - /*guint8 buff[1024]; - goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); - int got = - goodix_tls_server_receive(priv->tls_hop, buff, sizeof(buff), &err); - if (got <= 0) { - fp_err("failed to read ssl stream: %s (code: %d)", err->message, - err->code); - return; - } - fp_dbg("GOT, len: %d, %s", got, data_to_str(buff, got));*/ } static void goodix_tls_ready(GoodixTlsServer* server, GError* err, gpointer dev) @@ -1170,7 +1147,6 @@ static void goodix_tls_ready(GoodixTlsServer* server, GError* err, gpointer dev) err->code); return; } - fp_dbg("Inited tls server"); goodix_send_request_tls_connection(FP_DEVICE(dev), on_goodix_request_tls_connection, dev); } @@ -1195,10 +1171,7 @@ void goodix_tls(FpDevice *dev) { err->code); return; } - /*if (!goodix_tls_init_cli(s, &err)) { - fp_err("failed to init client: %s, code: %d", err->message, err->code); - return; - }*/ + goodix_tls_ready(s, err, self); } diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 2750b1c82..37d78ff66 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -70,31 +70,6 @@ static unsigned int tls_server_psk_server_callback(SSL *ssl, return len; } -static int tls_server_create_socket(int port) -{ - int s; - struct sockaddr_in addr; - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) { - return -1; - } - - if (bind(s, (struct sockaddr*) &addr, sizeof(addr)) < 0) { - return -1; - } - - if (listen(s, 1) < 0) { - return -1; - } - - return s; -} - static SSL_CTX* tls_server_create_ctx(void) { const SSL_METHOD* method; @@ -108,12 +83,6 @@ static SSL_CTX* tls_server_create_ctx(void) return ctx; } -static SSL_CTX* tls_cli_create_ctx() -{ - const SSL_METHOD* method = TLS_client_method(); - SSL_CTX* ctx = SSL_CTX_new(method); - return ctx; -} static void tls_server_config_ctx(SSL_CTX* ctx) { @@ -122,38 +91,9 @@ static void tls_server_config_ctx(SSL_CTX* ctx) SSL_CTX_set_cipher_list(ctx, "ALL"); SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); - // SSL_CTX_set_cipher_list(ctx, "ALL"); SSL_CTX_set_psk_server_callback(ctx, tls_server_psk_server_callback); } -static gboolean goodix_tls_connect(GoodixTlsServer* self) -{ - struct sockaddr_in addr; - guint len = sizeof(addr); - - int client_fd = accept(self->sock_fd, (struct sockaddr*) &addr, &len); - if (client_fd >= 0) { - } - - GError err; - err.code = errno; - err.message = strerror(errno); - self->connection_callback(self, &err, self->user_data); - return FALSE; -} -static void goodix_tls_send_handshake(GoodixTlsServer* self) -{ - const char reply[] = "Hello Goodix\n"; - SSL_write(self->ssl_layer, reply, strlen(reply)); -} - -void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, guint16 length) -{ - fp_dbg("Sending data to goodix tls server"); - SSL_write(self->ssl_layer, data, length * sizeof(guint8)); - // send(self->client_fd, data, length * sizeof(guint8), 0); -} - int goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length) { return write(self->client_fd, data, length * sizeof(guint8)); @@ -183,28 +123,6 @@ static void tls_config_ssl(SSL* ssl) SSL_set_cipher_list(ssl, "ALL"); } -gboolean goodix_tls_init_cli(GoodixTlsServer* self, GError** error) -{ - SSL_CTX* ctx = tls_cli_create_ctx(); - // tls_server_config_ctx(ctx); - SSL* ssl_layer = SSL_new(ctx); - tls_config_ssl(ssl_layer); - - int retr = SSL_set_fd(ssl_layer, self->client_fd); - - if (retr > 0) { - retr = SSL_connect(ssl_layer); - } - - if (retr <= 0) { - //*error = err_from_ssl(retr); - } - // SSL_free(ssl_layer); - // SSL_CTX_free(ctx); - - return retr <= 0 ? 0 : 1; -} - static void* goodix_tls_init_serve(void* me) { GoodixTlsServer* self = me; @@ -218,23 +136,6 @@ static void* goodix_tls_init_serve(void* me) self->connection_callback(self, err_from_ssl(), self->user_data); } else { - g_assert(self->connection_callback); - const char* msg = "HELLO WORLD"; - // SSL_write(self->ssl_layer, msg, strlen(msg)); - - /*char buff[1024]; - int qty = SSL_read(self->ssl_layer, buff, sizeof(buff) - 1); - if (qty <= 0) { - self->connection_callback( - self, - g_error_new(G_FILE_ERROR, SSL_get_error(self->ssl_layer, qty), - ""), - self->user_data); - return NULL; - } - buff[qty] = 0;*/ - - // fp_dbg("Finished tls setup server side, got: %s (%d)", buff, qty); self->connection_callback(self, NULL, self->user_data); } return NULL; @@ -245,9 +146,6 @@ gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error) SSL_shutdown(self->ssl_layer); SSL_free(self->ssl_layer); - // SSL_shutdown(self->ssl_layer); - // SSL_free(self->ssl_layer); - close(self->client_fd); close(self->sock_fd); @@ -258,9 +156,7 @@ gboolean goodix_tls_server_deinit(GoodixTlsServer* self, GError** error) gboolean goodix_tls_server_init(GoodixTlsServer* self, GError** error) { - // g_assert(self->decoded_callback); g_assert(self->connection_callback); - // g_assert(self->send_callback); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); SSL_library_init(); diff --git a/libfprint/drivers/goodixtls/goodixtls.h b/libfprint/drivers/goodixtls/goodixtls.h index 16167afbc..8555c20b8 100644 --- a/libfprint/drivers/goodixtls/goodixtls.h +++ b/libfprint/drivers/goodixtls/goodixtls.h @@ -81,9 +81,6 @@ gboolean goodix_tls_init_cli(GoodixTlsServer* self, GError** err); int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, guint16 length, GError** error); -void goodix_tls_server_send(GoodixTlsServer* self, guint8* data, - guint16 length); - int goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length); int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length); From 84acfb1f452791afbd8e7d81f84e7a04dab3813d Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Thu, 2 Sep 2021 21:55:34 +0100 Subject: [PATCH 09/57] chore: move handshake to state machine --- libfprint/drivers/goodixtls/goodix.c | 125 ++++++++++++++++----------- 1 file changed, 74 insertions(+), 51 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 6ae695a33..2e13009fe 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -17,6 +17,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include "fpi-ssm.h" #include "fpi-usb-transfer.h" #define FP_COMPONENT "goodixtls" @@ -1044,67 +1045,104 @@ static void on_goodix_tls_server_ready(GoodixTlsServer* server, GError* err, fpi_device_goodixtls_get_instance_private(self); fp_dbg("TLS connection ready"); } -typedef struct _goodix_tls_handshake_state { - int count; - void (*callback)(FpDevice*, GError*, struct _goodix_tls_handshake_state*); - FpDevice* dev; - -} goodix_tls_handshake_state; static void on_goodix_tls_read_handshake(FpDevice* dev, guint8* data, guint16 length, gpointer user_data, GError* error) { - goodix_tls_handshake_state* state = (goodix_tls_handshake_state*) user_data; + // goodix_tls_handshake_state* state = (goodix_tls_handshake_state*) + // user_data; + FpiSsm* ssm = user_data; if (error) { - fp_err("failed to read tls during handshake: %s, code: %d", - error->message, error->code); - state->callback(dev, error, state); + fpi_ssm_mark_failed(ssm, error); return; } - FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(state->dev); + FpiDeviceGoodixTls* self = + FPI_DEVICE_GOODIXTLS(fpi_ssm_get_data(user_data)); FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); - fp_dbg("handshake loop, got: %s, size: %d", data_to_str(data, length), - length); int sent = goodix_tls_client_send(priv->tls_hop, data, length); - fp_dbg("sent: %d bytes", sent); + if (sent < 0) { + fpi_ssm_mark_failed(ssm, g_error_new(g_io_error_quark(), sent, + "failed to sent data to " + "tls server")); + return; + } + fpi_ssm_next_state(ssm); +} + +enum goodix_tls_handshake_stages { + TLS_HANDSHAKE_STAGE_HELLO_S, + TLS_HANDSHAKE_STAGE_KH_EXCHANGE, + TLS_HANDSHAKE_STAGE_CHANGE_CIPHER_C, + TLS_HANDSHAKE_STAGE_HANDSHAKE_C, + TLS_HANDSHAKE_STAGE_CHANGE_CIPHER_S, - if (state->count >= 2) { + TLS_HANDSHAKE_STAGE_NUM, +}; +static void tls_handshake_done(FpiSsm* ssm, FpDevice* dev, GError* error) +{ + if (error) { + fp_dbg("failed to do tls handshake: %s (code: %d)", error->message, + error->code); + } + goodix_send_tls_successfully_established(dev, NULL, NULL); + + fp_dbg("HANDSHAKE DONE"); +} +static void tls_handshake_run(FpiSsm* ssm, FpDevice* dev) +{ + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + + int stage = fpi_ssm_get_cur_state(ssm); + if (stage == TLS_HANDSHAKE_STAGE_HELLO_S) { + guint8 buff[1024]; + int size = goodix_tls_client_recv(priv->tls_hop, buff, sizeof(buff)); + if (size < 0) { + fpi_ssm_mark_failed(ssm, g_error_new(g_io_error_quark(), size, + "failed to read tls server " + "hello")); + return; + } + GError* err = NULL; + if (!goodix_send_pack(dev, GOODIX_FLAGS_TLS, buff, size, NULL, &err)) { + fpi_ssm_mark_failed(ssm, err); + return; + } + fpi_ssm_next_state(ssm); + } + else if (stage < TLS_HANDSHAKE_STAGE_CHANGE_CIPHER_S) { + // Still proxying from hardware + fpi_ssm_set_data(ssm, dev, NULL); + goodix_read_tls(dev, on_goodix_tls_read_handshake, ssm); + } + else if (stage == TLS_HANDSHAKE_STAGE_CHANGE_CIPHER_S) { fp_dbg("Reading to proxy back"); guint8 buff[1024]; int size = goodix_tls_client_recv(priv->tls_hop, buff, sizeof(buff)); if (size < 0) { - fp_err("failed to recieve from server: %d", size); + fpi_ssm_mark_failed(ssm, g_error_new(g_io_error_quark(), size, + "failed to read server " + "handshake")); - state->callback(dev, g_error_new(g_io_error_quark(), size, ""), - state); return; } - fp_dbg("got: %s from the server (size: %d)", data_to_str(buff, size), - size); GError* err = NULL; if (!goodix_send_data(dev, buff, size, NULL, &err)) { - fp_err("failed to send tls data back: %s, code: %d", err->message, - err->code); - state->callback(dev, err, state); + fpi_ssm_mark_failed(ssm, err); return; } - state->callback(dev, NULL, state); - } - else { - ++state->count; - goodix_read_tls(dev, on_goodix_tls_read_handshake, state); + fpi_ssm_next_state(ssm); } } -static void on_goodix_tls_handshake_done(FpDevice* dev, GError* err, - goodix_tls_handshake_state* state) -{ - fp_dbg("DONE"); - free(state); - goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); +static void do_tls_handshake(FpDevice* dev) +{ + fpi_ssm_start(fpi_ssm_new(dev, tls_handshake_run, TLS_HANDSHAKE_STAGE_NUM), + tls_handshake_done); } static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, @@ -1119,25 +1157,10 @@ static void on_goodix_request_tls_connection(FpDevice* dev, guint8* data, FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(user_data); FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); - GError* err = NULL; - fp_dbg("len: %d, d: %s", length, data_to_str(data, length)); goodix_tls_client_send(priv->tls_hop, data, length); - guint8 buff[1024]; - int size = goodix_tls_client_recv(priv->tls_hop, buff, sizeof(buff)); - if (size < 0) { - fp_err("failed to read: %d", size); - goodix_send_tls_successfully_established(FP_DEVICE(dev), NULL, NULL); - return; - } - goodix_send_pack(dev, GOODIX_FLAGS_TLS, buff, size, NULL, &err); - - goodix_tls_handshake_state* hs_st = - malloc(sizeof(goodix_tls_handshake_state)); - hs_st->callback = on_goodix_tls_handshake_done; - hs_st->dev = dev; - hs_st->count = 0; - goodix_read_tls(dev, on_goodix_tls_read_handshake, hs_st); + + do_tls_handshake(dev); } static void goodix_tls_ready(GoodixTlsServer* server, GError* err, gpointer dev) From 6e04a91b067c82328e02df09931eb7f7b0ea8a10 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Fri, 3 Sep 2021 00:09:39 +0100 Subject: [PATCH 10/57] chore: working on tls images --- libfprint/drivers/goodixtls/goodix.c | 86 +++++++++++++--- libfprint/drivers/goodixtls/goodix.h | 10 +- libfprint/drivers/goodixtls/goodix511.c | 108 ++++++++++++++++++++- libfprint/drivers/goodixtls/goodix_proto.c | 3 +- libfprint/drivers/goodixtls/goodix_proto.h | 2 +- libfprint/drivers/goodixtls/goodixtls.c | 3 +- libfprint/drivers/goodixtls/goodixtls.h | 2 +- 7 files changed, 193 insertions(+), 21 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 2e13009fe..cdd9a9d43 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -43,12 +43,15 @@ typedef struct { gboolean ack; gboolean reply; + gboolean tls; GoodixCmdCallback callback; gpointer user_data; guint8* data; guint32 length; + + GoodixCallbackInfo* tls_ready_callback; } FpiDeviceGoodixTlsPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(FpiDeviceGoodixTls, fpi_device_goodixtls, @@ -360,6 +363,7 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { if (!goodix_decode_pack(priv->data, priv->length, &flags, &payload, &payload_len, &valid_checksum)) { // Packet is not full, we still need data. + fp_dbg("not full packet"); return; } @@ -371,6 +375,9 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { case GOODIX_FLAGS_TLS: fp_dbg("Got TLS msg"); + if (!priv->tls) { + fp_warn("unexpected tls packet"); + } goodix_receive_done(dev, payload, payload_len, NULL); // TLS message sending it to TLS server. @@ -534,7 +541,7 @@ void goodix_send_nop(FpDevice *dev, GoodixNoneCallback callback, goodix_receive_done(dev, NULL, 0, NULL); } -void goodix_send_mcu_get_image(FpDevice* dev, GoodixNoneCallback callback, +void goodix_send_mcu_get_image(FpDevice* dev, GoodixImageCallback callback, gpointer user_data) { GoodixDefault payload = {.unused_flags = 0x01}; @@ -547,13 +554,13 @@ void goodix_send_mcu_get_image(FpDevice* dev, GoodixNoneCallback callback, cb_info->user_data = user_data; goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, (guint8*) &payload, - sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, FALSE, - goodix_receive_none, cb_info); + sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, TRUE, + goodix_receive_default, cb_info); return; } goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, (guint8*) &payload, - sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, FALSE, + sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, TRUE, NULL, NULL); } @@ -1024,6 +1031,7 @@ void goodix_read_tls(FpDevice* dev, GoodixTlsCallback callback, priv->callback = callback; priv->user_data = user_data; priv->reply = TRUE; + priv->cmd = 0; goodix_receive_data(FP_DEVICE(self)); } @@ -1040,9 +1048,6 @@ static void on_goodix_tls_server_ready(GoodixTlsServer* server, GError* err, fp_err("server ready failed: %s", err->message); return; } - FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); - FpiDeviceGoodixTlsPrivate* priv = - fpi_device_goodixtls_get_instance_private(self); fp_dbg("TLS connection ready"); } @@ -1081,15 +1086,26 @@ enum goodix_tls_handshake_stages { TLS_HANDSHAKE_STAGE_NUM, }; + +static void on_tls_successfully_established(FpDevice* dev, gpointer user_data, + GError* error) +{ + + fp_dbg("HANDSHAKE DONE"); + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + ((GoodixNoneCallback) priv->tls_ready_callback->callback)( + dev, priv->tls_ready_callback->user_data, NULL); +} static void tls_handshake_done(FpiSsm* ssm, FpDevice* dev, GError* error) { if (error) { fp_dbg("failed to do tls handshake: %s (code: %d)", error->message, error->code); } - goodix_send_tls_successfully_established(dev, NULL, NULL); - - fp_dbg("HANDSHAKE DONE"); + goodix_send_tls_successfully_established( + dev, on_tls_successfully_established, NULL); } static void tls_handshake_run(FpiSsm* ssm, FpDevice* dev) { @@ -1178,13 +1194,20 @@ void goodix_tls_complete(FpiSsm *ssm, FpDevice *dev, GError *error) { fpi_image_device_activate_complete(FP_IMAGE_DEVICE(dev), error); } -void goodix_tls(FpDevice *dev) { +void goodix_tls(FpDevice* dev, GoodixNoneCallback callback, gpointer user_data) +{ fp_dbg("Starting up goodix tls server"); FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); g_assert(priv->tls_hop == NULL); priv->tls_hop = malloc(sizeof(GoodixTlsServer)); + + if (!priv->tls_ready_callback) { + priv->tls_ready_callback = malloc(sizeof(GoodixCallbackInfo)); + } + priv->tls_ready_callback->callback = G_CALLBACK(callback); + priv->tls_ready_callback->user_data = user_data; GoodixTlsServer* s = priv->tls_hop; s->connection_callback = on_goodix_tls_server_ready; s->user_data = self; @@ -1197,6 +1220,47 @@ void goodix_tls(FpDevice *dev) { goodix_tls_ready(s, err, self); } +static void goodix_tls_ready_image_handler(FpDevice* dev, guint8* data, + guint16 length, gpointer user_data, + GError* error) +{ + + g_autofree GoodixCallbackInfo* cb_info = user_data; + GoodixImageCallback callback = (GoodixImageCallback) cb_info->callback; + if (error) { + callback(dev, NULL, 0, error, cb_info->user_data); + return; + } + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + goodix_tls_client_send(priv->tls_hop, data, length); + + const guint16 size = -1; + guint8* buff = malloc(size); + GError* err = NULL; + if (!goodix_tls_server_receive(priv->tls_hop, buff, size, &err)) { + callback(dev, NULL, 0, err, cb_info->user_data); + return; + } + + callback(dev, buff, size, cb_info->user_data, NULL); +} + +void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, + gpointer user_data) +{ + g_assert(callback); + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + GoodixCallbackInfo* cb_info = malloc(sizeof(GoodixImageCallback)); + + cb_info->callback = G_CALLBACK(callback); + cb_info->user_data = user_data; + + goodix_send_mcu_get_image(dev, goodix_tls_ready_image_handler, cb_info); +} // ---- TLS SECTION END ---- diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index 04f57c0c1..7e8a97997 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -67,6 +67,9 @@ typedef void (*GoodixDefaultCallback)(FpDevice *dev, guint8 *data, GError *error); typedef GoodixDefaultCallback GoodixTlsCallback; +typedef void (*GoodixImageCallback)(FpDevice* dev, guint8* data, guint16 length, + gpointer user_data, GError* error); + gchar *data_to_str(guint8 *data, guint32 length); // ---- GOODIX RECEIVE SECTION START ---- @@ -133,7 +136,7 @@ void goodix_send_protocol(FpDevice *dev, guint8 cmd, guint8 *payload, void goodix_send_nop(FpDevice *dev, GoodixNoneCallback callback, gpointer user_data); -void goodix_send_mcu_get_image(FpDevice *dev, GoodixNoneCallback callback, +void goodix_send_mcu_get_image(FpDevice *dev, GoodixImageCallback callback, gpointer user_data); void goodix_send_mcu_switch_to_fdt_down(FpDevice *dev, guint8 *mode, @@ -233,6 +236,9 @@ void goodix_tls_run_state(FpiSsm* ssm, FpDevice* dev); void goodix_tls_complete(FpiSsm *ssm, FpDevice *dev, GError *error); -void goodix_tls(FpDevice *dev); +void goodix_tls(FpDevice* dev, GoodixNoneCallback callback, gpointer user_data); + +void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, + gpointer user_data); // ---- TLS SECTION END ---- diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 81ea66b1d..c6a838b46 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -22,7 +22,9 @@ #include "fpi-assembling.h" #include "fpi-image-device.h" #include "fpi-ssm.h" +#include "glibconfig.h" #include "gusb/gusb-device.h" +#include #define FP_COMPONENT "goodixtls511" #include @@ -249,20 +251,119 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev) { } } -static void activate_complete(FpiSsm *ssm, FpDevice *dev, GError *error) { - G_DEBUG_HERE(); +static void tls_activation_complete(FpDevice* dev, gpointer user_data, + GError* error) +{ + if (error) { + fp_err("failed to complete tls activation: %s", error->message); + return; + } FpImageDevice* image_dev = FP_IMAGE_DEVICE(dev); fpi_image_device_activate_complete(image_dev, error); +} +static void activate_complete(FpiSsm* ssm, FpDevice* dev, GError* error) +{ + G_DEBUG_HERE(); if (!error) - goodix_tls(dev); + goodix_tls(dev, tls_activation_complete, NULL); } // ---- ACTIVE SECTION END ---- // ----------------------------------------------------------------------------- +// ---- SCAN SECTION START ---- + +enum SCAN_STAGES { + SCAN_STAGE_SWITCH_TO_FDT_MODE, + SCAN_STAGE_SWITCH_TO_FDT_DOWN, + SCAN_STAGE_GET_IMG, + + SCAN_STAGE_NUM, +}; + +static void check_none_cmd(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + fpi_ssm_next_state(ssm); +} + +static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + fp_dbg("Got image"); + FILE* out = fopen("./fingerprint.pgm", "wb"); + fwrite(data, sizeof(guint8), len, out); + fclose(out); + fpi_ssm_next_state(ssm); +} + +static void scan_get_img(FpDevice* dev, FpiSsm* ssm) +{ + goodix_tls_read_image(dev, scan_on_read_img, ssm); +} +const guint8 fdt_switch_state_mode[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, 0xa4, + 0x80, 0xb8, 0x80, 0xa8, 0x80, 0xb7}; + +const guint8 fdt_switch_state_down[] = {0x0c, 0x01, 0x80, 0xaf, 0x80, 0xa4, + 0x80, 0xb8, 0x80, 0xa8, 0x80, 0xb7}; + +/* + +const guint8 fdt_switch_state_mode[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, 0xa3, + 0x80, 0xb7, 0x80, 0xa7, 0x80, 0xb6}; + +const guint8 fdt_switch_state_down[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, + 0xbf, 0x80, 0xa4, 0x80, 0xb8, + 0x80, 0xa8, 0x80, 0xb7}; + */ + +static void scan_run_state(FpiSsm* ssm, FpDevice* dev) +{ + switch (fpi_ssm_get_cur_state(ssm)) { + case SCAN_STAGE_SWITCH_TO_FDT_MODE: + goodix_send_mcu_switch_to_fdt_mode(dev, fdt_switch_state_mode, + sizeof(fdt_switch_state_mode), NULL, + check_none_cmd, ssm); + break; + case SCAN_STAGE_SWITCH_TO_FDT_DOWN: + goodix_send_mcu_switch_to_fdt_down(dev, fdt_switch_state_down, + sizeof(fdt_switch_state_down), NULL, + check_none_cmd, ssm); + break; + case SCAN_STAGE_GET_IMG: + scan_get_img(dev, ssm); + break; + } +} + +static void scan_complete(FpiSsm* ssm, FpDevice* dev, GError* error) +{ + if (error) { + fp_err("failed to scan: %s (code: %d)", error->message, error->code); + return; + } + fp_dbg("finished scan"); +} + +static void scan_start(FpiDeviceGoodixTls511* dev) +{ + fpi_ssm_start(fpi_ssm_new(FP_DEVICE(dev), scan_run_state, SCAN_STAGE_NUM), + scan_complete); +} + +// ---- SCAN SECTION END ---- + // ---- DEV SECTION START ---- static void dev_init(FpImageDevice *img_dev) { @@ -304,6 +405,7 @@ static void dev_change_state(FpImageDevice* img_dev, FpiImageDeviceState state) G_DEBUG_HERE(); if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON) { + scan_start(self); } } diff --git a/libfprint/drivers/goodixtls/goodix_proto.c b/libfprint/drivers/goodixtls/goodix_proto.c index 0f61b5f46..1b2aafa80 100644 --- a/libfprint/drivers/goodixtls/goodix_proto.c +++ b/libfprint/drivers/goodixtls/goodix_proto.c @@ -84,8 +84,7 @@ gboolean goodix_decode_pack(guint8 *data, guint32 data_len, guint8 *flags, if (data_len < sizeof(GoodixPack) + sizeof(guint8)) return FALSE; - length = pack->length; // length = GUINT16_FROM_LE(pack->length); - printf("SIZE: %d\n", length); + length = GUINT16_FROM_LE(pack->length); if (data_len < length + sizeof(GoodixPack) + sizeof(guint8)) return FALSE; diff --git a/libfprint/drivers/goodixtls/goodix_proto.h b/libfprint/drivers/goodixtls/goodix_proto.h index d42ca870e..ac27ce63e 100644 --- a/libfprint/drivers/goodixtls/goodix_proto.h +++ b/libfprint/drivers/goodixtls/goodix_proto.h @@ -19,7 +19,7 @@ #pragma once -#define GOODIX_EP_IN_MAX_BUF_SIZE (0x2000) +#define GOODIX_EP_IN_MAX_BUF_SIZE (0x10000) #define GOODIX_EP_OUT_MAX_BUF_SIZE (0x40) #define GOODIX_NULL_CHECKSUM (0x88) diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 37d78ff66..10e76712f 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -96,6 +96,7 @@ static void tls_server_config_ctx(SSL_CTX* ctx) int goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length) { + fp_dbg("sent: %s size: %d", data_to_str(data, length), length); return write(self->client_fd, data, length * sizeof(guint8)); } int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length) { @@ -103,7 +104,7 @@ int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length) } int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, - guint16 length, GError** error) + guint32 length, GError** error) { fp_dbg("READ START"); int retr = SSL_read(self->ssl_layer, data, length * sizeof(guint8)); diff --git a/libfprint/drivers/goodixtls/goodixtls.h b/libfprint/drivers/goodixtls/goodixtls.h index 8555c20b8..a7d5b9490 100644 --- a/libfprint/drivers/goodixtls/goodixtls.h +++ b/libfprint/drivers/goodixtls/goodixtls.h @@ -79,7 +79,7 @@ gboolean goodix_tls_init_cli(GoodixTlsServer* self, GError** err); // This can be called multiple times. It is called when the device send a TLS // packet. int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, - guint16 length, GError** error); + guint32 length, GError** error); int goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length); From 5ab48b4813b3e3c9122177f7e167cbe823477f3c Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Fri, 3 Sep 2021 19:48:54 +0100 Subject: [PATCH 11/57] feat: add otp writing --- libfprint/drivers/goodixtls/goodix.c | 23 +++++++++ libfprint/drivers/goodixtls/goodix.h | 3 ++ libfprint/drivers/goodixtls/goodix511.c | 65 +++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index cdd9a9d43..f6b3dc46e 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -921,6 +921,29 @@ void goodix_send_tls_successfully_established(FpDevice *dev, GOODIX_TIMEOUT, FALSE, NULL, NULL); } +void goodix_send_read_otp(FpDevice* dev, GoodixDefaultCallback callback, + gpointer user_data) +{ + GoodixNone payload = {}; + GoodixCallbackInfo* cb_info; + + if (callback) { + cb_info = malloc(sizeof(GoodixCallbackInfo)); + + cb_info->callback = G_CALLBACK(callback); + cb_info->user_data = user_data; + + goodix_send_protocol(dev, GOODIX_CMD_READ_OTP, (guint8*) &payload, + sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, TRUE, + goodix_receive_default, cb_info); + return; + } + + goodix_send_protocol(dev, GOODIX_CMD_READ_OTP, (guint8*) &payload, + sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, TRUE, + NULL, NULL); +} + void goodix_send_preset_psk_write(FpDevice *dev, guint32 flags, guint8 *psk, guint16 length, GDestroyNotify free_func, GoodixSuccessCallback callback, diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index 7e8a97997..fbbcbedde 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -213,6 +213,9 @@ void goodix_send_preset_psk_read(FpDevice *dev, guint32 flags, guint16 length, GoodixPresetPskReadCallback callback, gpointer user_data); +void goodix_send_read_otp(FpDevice* dev, GoodixDefaultCallback callback, + gpointer user_data); + // ---- GOODIX SEND SECTION END ---- // ----------------------------------------------------------------------------- diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index c6a838b46..97ffd2314 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -20,6 +20,7 @@ #include "fp-device.h" #include "fp-image-device.h" #include "fpi-assembling.h" +#include "fpi-context.h" #include "fpi-image-device.h" #include "fpi-ssm.h" #include "glibconfig.h" @@ -37,6 +38,9 @@ struct _FpiDeviceGoodixTls511 { FpiDeviceGoodixTls parent; + + guint8* otp; + guint16 otp_len; }; G_DECLARE_FINAL_TYPE(FpiDeviceGoodixTls511, fpi_device_goodixtls511, FPI, @@ -55,6 +59,7 @@ enum activate_states { ACTIVATE_CHECK_PSK, ACTIVATE_RESET, ACTIVATE_SET_MCU_IDLE, + ACTIVATE_SET_ODP, ACTIVATE_SET_MCU_CONFIG, ACTIVATE_SET_POWERDOWN_SCAN_FREQUENCY, ACTIVATE_NUM_STATES, @@ -198,6 +203,63 @@ static void check_powerdown_scan_freq(FpDevice* dev, gboolean success, fpi_ssm_next_state(user_data); } } + +enum otp_write_states { + OTP_WRITE_1, + OTP_WRITE_2, + OTP_WRITE_3, + OTP_WRITE_4, + + OTP_WRITE_NUM, +}; + +static guint16 otp_write_addrs[] = {0x0220, 0x0236, 0x0238, 0x023a}; + +static void otp_write_run(FpiSsm* ssm, FpDevice* dev) +{ + guint16 data; + FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); + guint8* otp = self->otp; + switch (fpi_ssm_get_cur_state(ssm)) { + case OTP_WRITE_1: + data = GUINT16_FROM_LE(otp[46] << 4 | 8); + break; + case OTP_WRITE_2: + data = GUINT16_FROM_LE(otp[47]); + break; + case OTP_WRITE_3: + data = GUINT16_FROM_LE(otp[48]); + break; + case OTP_WRITE_4: + data = GUINT16_FROM_LE(otp[49]); + break; + } + + goodix_send_write_sensor_register( + dev, otp_write_addrs[fpi_ssm_get_cur_state(ssm)], data, check_none, + ssm); +} + +static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + if (len < 64) { + fpi_ssm_mark_failed(ssm, g_error_new(FP_DEVICE_ERROR, + FP_DEVICE_ERROR_DATA_INVALID, + "OTP is invalid (len: %d)", 64)); + return; + } + FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); + self->otp = data; + self->otp_len = len; + FpiSsm* otp_ssm = fpi_ssm_new(dev, otp_write_run, OTP_WRITE_NUM); + fpi_ssm_start_subsm(ssm, otp_ssm); +} + static void activate_run_state(FpiSsm *ssm, FpDevice *dev) { GError *error = NULL; @@ -238,6 +300,9 @@ static void activate_run_state(FpiSsm *ssm, FpDevice *dev) { goodix_send_mcu_switch_to_idle_mode(dev, 20, check_idle, ssm); break; + case ACTIVATE_SET_ODP: + goodix_send_read_otp(dev, read_otp_callback, ssm); + break; case ACTIVATE_SET_MCU_CONFIG: goodix_send_upload_config_mcu(dev, goodix_511_config, sizeof(goodix_511_config), NULL, From 4b49e1e43344a3a8517f0e6f5f7c1ff1156439e3 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Fri, 3 Sep 2021 20:19:17 +0100 Subject: [PATCH 12/57] fix: incorrectly packaged tls handshake data --- libfprint/drivers/goodixtls/goodix.c | 38 +++++++++++++++------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index f6b3dc46e..ff039c80c 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -441,23 +441,24 @@ void goodix_receive_data(FpDevice *dev) { gboolean goodix_send_data(FpDevice *dev, guint8 *data, guint32 length, GDestroyNotify free_func, GError **error) { - FpiDeviceGoodixTls *self = FPI_DEVICE_GOODIXTLS(dev); - FpiDeviceGoodixTlsClass* class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); - - for (guint32 i = 0; i < length; i += GOODIX_EP_OUT_MAX_BUF_SIZE) { - FpiUsbTransfer* transfer = fpi_usb_transfer_new(dev); - transfer->short_is_error = TRUE; - - fpi_usb_transfer_fill_bulk_full(transfer, class->ep_out, data + i, - GOODIX_EP_OUT_MAX_BUF_SIZE, NULL); - - if (!fpi_usb_transfer_submit_sync(transfer, GOODIX_TIMEOUT, error)) { - if (free_func) - free_func(data); - fpi_usb_transfer_unref(transfer); - return FALSE; - } - fpi_usb_transfer_unref(transfer); + fp_dbg("--- SEND DATA SIZE: %d ---", length); + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsClass* class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); + + for (guint32 i = 0; i < length; i += GOODIX_EP_OUT_MAX_BUF_SIZE) { + FpiUsbTransfer* transfer = fpi_usb_transfer_new(dev); + transfer->short_is_error = TRUE; + + fpi_usb_transfer_fill_bulk_full(transfer, class->ep_out, data + i, + GOODIX_EP_OUT_MAX_BUF_SIZE, NULL); + + if (!fpi_usb_transfer_submit_sync(transfer, GOODIX_TIMEOUT, error)) { + if (free_func) + free_func(data); + fpi_usb_transfer_unref(transfer); + return FALSE; + } + fpi_usb_transfer_unref(transfer); } if (free_func) @@ -1130,6 +1131,7 @@ static void tls_handshake_done(FpiSsm* ssm, FpDevice* dev, GError* error) goodix_send_tls_successfully_established( dev, on_tls_successfully_established, NULL); } + static void tls_handshake_run(FpiSsm* ssm, FpDevice* dev) { FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); @@ -1170,7 +1172,7 @@ static void tls_handshake_run(FpiSsm* ssm, FpDevice* dev) return; } GError* err = NULL; - if (!goodix_send_data(dev, buff, size, NULL, &err)) { + if (!goodix_send_pack(dev, GOODIX_FLAGS_TLS, buff, size, NULL, &err)) { fpi_ssm_mark_failed(ssm, err); return; } From 83c4ba518e68a4224f3d0235363944147e4f64ed Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 13:34:59 +0100 Subject: [PATCH 13/57] fix: magic bytes. Now waits for finger! --- libfprint/drivers/goodixtls/goodix.c | 24 ++-- libfprint/drivers/goodixtls/goodix.h | 2 + libfprint/drivers/goodixtls/goodix511.c | 159 +++++++++++++++++++----- libfprint/drivers/goodixtls/goodixtls.c | 3 - 4 files changed, 143 insertions(+), 45 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index ff039c80c..d17c0fd88 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -737,19 +737,18 @@ void goodix_send_upload_config_mcu(FpDevice *dev, guint8 *config, guint16 length, GDestroyNotify free_func, GoodixSuccessCallback callback, gpointer user_data) { - GoodixCallbackInfo *cb_info; - ; + GoodixCallbackInfo* cb_info; - if (callback) { - cb_info = malloc(sizeof(GoodixCallbackInfo)); + if (callback) { + cb_info = malloc(sizeof(GoodixCallbackInfo)); - cb_info->callback = G_CALLBACK(callback); - cb_info->user_data = user_data; + cb_info->callback = G_CALLBACK(callback); + cb_info->user_data = user_data; - goodix_send_protocol(dev, GOODIX_CMD_UPLOAD_CONFIG_MCU, config, length, - free_func, TRUE, GOODIX_TIMEOUT, TRUE, - goodix_receive_success, cb_info); - return; + goodix_send_protocol(dev, GOODIX_CMD_UPLOAD_CONFIG_MCU, config, length, + free_func, TRUE, GOODIX_TIMEOUT, TRUE, + goodix_receive_success, cb_info); + return; } goodix_send_protocol(dev, GOODIX_CMD_UPLOAD_CONFIG_MCU, config, length, @@ -1264,12 +1263,13 @@ static void goodix_tls_ready_image_handler(FpDevice* dev, guint8* data, const guint16 size = -1; guint8* buff = malloc(size); GError* err = NULL; - if (!goodix_tls_server_receive(priv->tls_hop, buff, size, &err)) { + int read_size = goodix_tls_server_receive(priv->tls_hop, buff, size, &err); + if (read_size <= 0) { callback(dev, NULL, 0, err, cb_info->user_data); return; } - callback(dev, buff, size, cb_info->user_data, NULL); + callback(dev, buff, read_size, cb_info->user_data, NULL); } void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index fbbcbedde..6d0f55a27 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -244,4 +244,6 @@ void goodix_tls(FpDevice* dev, GoodixNoneCallback callback, gpointer user_data); void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, gpointer user_data); +void goodix_tls_decrypt_image(FpDevice* dev, guint8** data, guint16* len); + // ---- TLS SECTION END ---- diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 97ffd2314..5d719973c 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -19,9 +19,11 @@ #include "fp-device.h" #include "fp-image-device.h" +#include "fp-image.h" #include "fpi-assembling.h" #include "fpi-context.h" #include "fpi-image-device.h" +#include "fpi-image.h" #include "fpi-ssm.h" #include "glibconfig.h" #include "gusb/gusb-device.h" @@ -41,8 +43,12 @@ struct _FpiDeviceGoodixTls511 { guint8* otp; guint16 otp_len; + + GSList* frames; }; +#define GOODIXTLS_CAP_FRAMES 1 + G_DECLARE_FINAL_TYPE(FpiDeviceGoodixTls511, fpi_device_goodixtls511, FPI, DEVICE_GOODIXTLS511, FpiDeviceGoodixTls); @@ -222,16 +228,16 @@ static void otp_write_run(FpiSsm* ssm, FpDevice* dev) guint8* otp = self->otp; switch (fpi_ssm_get_cur_state(ssm)) { case OTP_WRITE_1: - data = GUINT16_FROM_LE(otp[46] << 4 | 8); + data = otp[46] << 4 | 8; break; case OTP_WRITE_2: - data = GUINT16_FROM_LE(otp[47]); + data = otp[47]; break; case OTP_WRITE_3: - data = GUINT16_FROM_LE(otp[48]); + data = otp[48]; break; case OTP_WRITE_4: - data = GUINT16_FROM_LE(otp[49]); + data = otp[49]; break; } @@ -342,9 +348,15 @@ static void activate_complete(FpiSsm* ssm, FpDevice* dev, GError* error) // ---- SCAN SECTION START ---- enum SCAN_STAGES { - SCAN_STAGE_SWITCH_TO_FDT_MODE, + SCAN_STAGE_QUERY_MCU, + SCAN_STAGE_SWITCH_TO_FDT_MODE_0, + SCAN_STAGE_NAV_0, + SCAN_STAGE_SWITCH_TO_FDT_MODE_1, + SCAN_STAGE_READ_REG, + SCAN_STAGE_GET_IMG_0, + SCAN_STAGE_SWITCH_TO_FDT_MODE_2, SCAN_STAGE_SWITCH_TO_FDT_DOWN, - SCAN_STAGE_GET_IMG, + SCAN_STAGE_GET_IMG_1, SCAN_STAGE_NUM, }; @@ -359,6 +371,37 @@ static void check_none_cmd(FpDevice* dev, guint8* data, guint16 len, fpi_ssm_next_state(ssm); } +static void write_pgm(guint8* data, guint16 len) +{ + g_assert(len != 0); + int needed = len / 6 * 4; + int* img = malloc(sizeof(int) * needed); + int* head = img; + for (int i = 0; i < len; i += 6) { + guint8* chunk = data + i; + *head++ = ((chunk[0] & 0xf) << 8) + chunk[1]; + *head++ = ((chunk[3] << 4) + (chunk[0] >> 4)); + *head++ = ((chunk[5] & 0xf) << 8) + chunk[2]; + *head++ = ((chunk[4] << 4) + (chunk[5] >> 4)); + } + FILE* out = fopen("./fingerprint.pgm", "w"); + const char buff[] = "P2\n88 80\n4095\n"; + fwrite(buff, sizeof(char), sizeof(buff), out); + int count = 0; + for (int* line = img; count < needed; line += 4) { + fwrite(line, sizeof(int), 4, out); + fwrite("\n", sizeof(char), 1, out); + count += 4; + } + fclose(out); + free(img); +} +static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, + struct fpi_frame* frame, unsigned int x, + unsigned int y) +{ + return frame->data[x + y * ctx->frame_width]; +} static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, gpointer ssm, GError* err) { @@ -366,10 +409,34 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, fpi_ssm_mark_failed(ssm, err); return; } - fp_dbg("Got image"); - FILE* out = fopen("./fingerprint.pgm", "wb"); - fwrite(data, sizeof(guint8), len, out); - fclose(out); + FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); + if (fpi_ssm_get_cur_state(ssm) == SCAN_STAGE_GET_IMG_1) { + if (g_slist_length(self->frames) > 1) { + self->frames = g_slist_append(self->frames, data); + fpi_ssm_jump_to_state(ssm, SCAN_STAGE_SWITCH_TO_FDT_MODE_2); + return; + } + else { + self->frames = g_slist_append(self->frames, data); + + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + struct fpi_frame_asmbl_ctx assembly_ctx; + assembly_ctx.frame_width = 80; + assembly_ctx.frame_height = 86; + assembly_ctx.image_width = 80; + assembly_ctx.get_pixel = get_pix; + + // write_pgm(data, len); + FpImage* img = fp_image_new(80, 88); + img->data = malloc(sizeof(guint8) * 80 * 88); + memcpy(img->data, data, 80 * 88); + img->flags |= FPI_IMAGE_PARTIAL; + + fpi_image_device_image_captured(img_dev, img); + fpi_image_device_report_finger_status(img_dev, FALSE); + } + } + fpi_ssm_next_state(ssm); } @@ -377,38 +444,67 @@ static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { goodix_tls_read_image(dev, scan_on_read_img, ssm); } -const guint8 fdt_switch_state_mode[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, 0xa4, - 0x80, 0xb8, 0x80, 0xa8, 0x80, 0xb7}; - -const guint8 fdt_switch_state_down[] = {0x0c, 0x01, 0x80, 0xaf, 0x80, 0xa4, - 0x80, 0xb8, 0x80, 0xa8, 0x80, 0xb7}; - -/* - -const guint8 fdt_switch_state_mode[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, 0xa3, - 0x80, 0xb7, 0x80, 0xa7, 0x80, 0xb6}; +const guint8 fdt_switch_state_mode_2[] = { + 0x0d, 0x01, 0x80, 0xaf, 0x80, 0xbf, 0x80, + 0xa4, 0x80, 0xb8, 0x80, 0xa8, 0x80, 0xb7, +}; +const guint8 fdt_switch_state_mode_0[] = {0x0d, 0x01, 0xae, 0xae, 0xbf, + 0xbf, 0xa4, 0xa4, 0xb8, 0xb8, + 0xa8, 0xa8, 0xb7, 0xb7}; +const guint8 fdt_switch_state_mode_1[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, 0xbf, + 0x80, 0xa3, 0x0d, 0x01, 0x80, 0xaf, + 0x80, 0xbf, 0x80, 0xa3}; + +const guint8 fdt_switch_state_down[] = { + 0x0c, 0x01, 0x80, 0xaf, 0x80, 0xbf, 0x80, + 0xa4, 0x80, 0xb8, 0x80, 0xa8, 0x80, 0xb7, +}; -const guint8 fdt_switch_state_down[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, - 0xbf, 0x80, 0xa4, 0x80, 0xb8, - 0x80, 0xa8, 0x80, 0xb7}; - */ +const guint8 fdt_switch_state_down_1[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, + 0xbf, 0x80, 0xa4, 0x80, 0xb8, + 0x80, 0xa8, 0x80, 0xb7}; static void scan_run_state(FpiSsm* ssm, FpDevice* dev) { + FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); switch (fpi_ssm_get_cur_state(ssm)) { - case SCAN_STAGE_SWITCH_TO_FDT_MODE: - goodix_send_mcu_switch_to_fdt_mode(dev, fdt_switch_state_mode, - sizeof(fdt_switch_state_mode), NULL, - check_none_cmd, ssm); + case SCAN_STAGE_QUERY_MCU: + goodix_send_query_mcu_state(dev, check_none_cmd, ssm); + break; + + case SCAN_STAGE_SWITCH_TO_FDT_MODE_0: + goodix_send_mcu_switch_to_fdt_mode(dev, fdt_switch_state_mode_0, + sizeof(fdt_switch_state_mode_0), + NULL, check_none_cmd, ssm); break; + case SCAN_STAGE_NAV_0: + goodix_send_nav_0(dev, check_none_cmd, ssm); + break; + case SCAN_STAGE_SWITCH_TO_FDT_MODE_1: + goodix_send_mcu_switch_to_fdt_mode(dev, fdt_switch_state_mode_1, + sizeof(fdt_switch_state_mode_1), + NULL, check_none_cmd, ssm); + break; + case SCAN_STAGE_SWITCH_TO_FDT_MODE_2: + goodix_send_mcu_switch_to_fdt_mode(dev, fdt_switch_state_mode_2, + sizeof(fdt_switch_state_mode_2), + NULL, check_none_cmd, ssm); + break; + case SCAN_STAGE_SWITCH_TO_FDT_DOWN: goodix_send_mcu_switch_to_fdt_down(dev, fdt_switch_state_down, sizeof(fdt_switch_state_down), NULL, check_none_cmd, ssm); break; - case SCAN_STAGE_GET_IMG: + case SCAN_STAGE_GET_IMG_1: + fpi_image_device_report_finger_status(img_dev, TRUE); + case SCAN_STAGE_GET_IMG_0: scan_get_img(dev, ssm); break; + case SCAN_STAGE_READ_REG: + goodix_send_read_sensor_register(dev, 0x0082, 2, check_none_cmd, ssm); + break; } } @@ -480,7 +576,10 @@ static void dev_deactivate(FpImageDevice *img_dev) { // ---- DEV SECTION END ---- -static void fpi_device_goodixtls511_init(FpiDeviceGoodixTls511 *self) {} +static void fpi_device_goodixtls511_init(FpiDeviceGoodixTls511* self) +{ + self->frames = g_slist_alloc(); +} static void fpi_device_goodixtls511_class_init( FpiDeviceGoodixTls511Class *class) { diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 10e76712f..473fc4b6b 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -96,7 +96,6 @@ static void tls_server_config_ctx(SSL_CTX* ctx) int goodix_tls_client_send(GoodixTlsServer* self, guint8* data, guint16 length) { - fp_dbg("sent: %s size: %d", data_to_str(data, length), length); return write(self->client_fd, data, length * sizeof(guint8)); } int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length) { @@ -106,13 +105,11 @@ int goodix_tls_client_recv(GoodixTlsServer* self, guint8* data, guint16 length) int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, guint32 length, GError** error) { - fp_dbg("READ START"); int retr = SSL_read(self->ssl_layer, data, length * sizeof(guint8)); if (retr <= 0) { g_set_error(error, g_io_channel_error_quark(), retr, ""); // err_from_ssl(retr); } - fp_dbg("READ END"); return retr; } From 1b5b49bdfe010fa61dc5c9e042c9ebdefc69650c Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 15:15:07 +0100 Subject: [PATCH 14/57] chore: working on frame decoding and assembly --- libfprint/drivers/goodixtls/goodix511.c | 55 ++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 5d719973c..2cf37d020 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -402,6 +402,37 @@ static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, { return frame->data[x + y * ctx->frame_width]; } + +#define GOODIX511_WIDTH 80 +#define GOODIX511_HEIGHT 88 +#define GOODIX511_FRAME_SIZE 80 * 88 +#define GOODIX511_RAW_FRAME_SIZE \ + GOODIX511_FRAME_SIZE / 4 * 6 // For every 4 pixels there are 6 bytes + +static void decode_frame(guint8* raw_frame, GSList** frames) +{ + const int frame_size = GOODIX511_FRAME_SIZE; + struct fpi_frame* frame = g_malloc(frame_size + sizeof(struct fpi_frame)); + raw_frame += 8; + + guint8* pix = frame->data; + for (int i = 0; i < GOODIX511_RAW_FRAME_SIZE; i += 6) { + guint8* chunk = raw_frame + i; + *pix++ = ((chunk[0] & 0xf) << 8) + chunk[1]; + *pix++ = ((chunk[3] << 4) + (chunk[0] >> 4)); + *pix++ = ((chunk[5] & 0xf) << 8) + chunk[2]; + *pix++ = ((chunk[4] << 4) + (chunk[5] >> 4)); + } + *frames = g_slist_append(*frames, frame); +} +static void write_frame(guint8* frame, GSList** frames) +{ + FILE* out = fopen("./fingerprint.pgm", "w"); + const char buff[] = "P2\n88 80\n4095\n"; + fwrite(buff, sizeof(char), sizeof(buff), out); + fwrite(frame, sizeof(guint8), GOODIX511_FRAME_SIZE, out); + fclose(out); +} static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, gpointer ssm, GError* err) { @@ -411,27 +442,41 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, } FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); if (fpi_ssm_get_cur_state(ssm) == SCAN_STAGE_GET_IMG_1) { - if (g_slist_length(self->frames) > 1) { + if (g_slist_length(self->frames) <= 3) { + /*GSList* frame = NULL; + // decode_frame(data, &frame); + FILE* f = fopen("./fingerraw.bin", "wb"); + fwrite(data, sizeof(guint8), len, f); + fclose(f); + // write_frame(g_slist_nth_data(frame, 0), NULL);*/ self->frames = g_slist_append(self->frames, data); fpi_ssm_jump_to_state(ssm, SCAN_STAGE_SWITCH_TO_FDT_MODE_2); return; } else { self->frames = g_slist_append(self->frames, data); + GSList* raw_frames = g_slist_nth(self->frames, 1); FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); struct fpi_frame_asmbl_ctx assembly_ctx; assembly_ctx.frame_width = 80; assembly_ctx.frame_height = 86; - assembly_ctx.image_width = 80; + assembly_ctx.image_width = 80 * 3 / 2; assembly_ctx.get_pixel = get_pix; + GSList* frames = NULL; + + g_slist_foreach(raw_frames, (GFunc) decode_frame, &frames); + // g_slist_foreach(g_slist_nth(frames, 1), (GFunc) write_frame, + // NULL); + // write_pgm(data, len); - FpImage* img = fp_image_new(80, 88); - img->data = malloc(sizeof(guint8) * 80 * 88); - memcpy(img->data, data, 80 * 88); + fpi_do_movement_estimation(&assembly_ctx, frames); + FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); img->flags |= FPI_IMAGE_PARTIAL; + g_slist_free_full(frames, g_free); + fpi_image_device_image_captured(img_dev, img); fpi_image_device_report_finger_status(img_dev, FALSE); } From 55a7cab74e6da8fb8606ee353fe38734b4db62e2 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 17:37:21 +0100 Subject: [PATCH 15/57] fix: initing new transfer per tls read --- libfprint/drivers/goodixtls/goodix.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index d17c0fd88..44317eadd 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -1055,7 +1055,6 @@ void goodix_read_tls(FpDevice* dev, GoodixTlsCallback callback, priv->user_data = user_data; priv->reply = TRUE; priv->cmd = 0; - goodix_receive_data(FP_DEVICE(self)); } enum tls_states { From da76817730240bca2e69097691723bd9f79fcc98 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 18:04:15 +0100 Subject: [PATCH 16/57] fix: otp accessing free'd memory --- libfprint/drivers/goodixtls/goodix511.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 2cf37d020..fdc3751ec 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -244,6 +244,10 @@ static void otp_write_run(FpiSsm* ssm, FpDevice* dev) goodix_send_write_sensor_register( dev, otp_write_addrs[fpi_ssm_get_cur_state(ssm)], data, check_none, ssm); + if (fpi_ssm_get_cur_state(ssm) == OTP_WRITE_NUM - 1) { + free(self->otp); + self->otp_len = 0; + } } static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, @@ -260,7 +264,8 @@ static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, return; } FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); - self->otp = data; + self->otp = malloc(len); + memcpy(self->otp, data, len); self->otp_len = len; FpiSsm* otp_ssm = fpi_ssm_new(dev, otp_write_run, OTP_WRITE_NUM); fpi_ssm_start_subsm(ssm, otp_ssm); From b270675435a612e8bc156142a841fe1c0f893ae0 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 21:58:30 +0100 Subject: [PATCH 17/57] feat: image decoding --- libfprint/drivers/goodixtls/goodix511.c | 87 +++++++------------------ 1 file changed, 25 insertions(+), 62 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index fdc3751ec..b9625ec39 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -38,6 +38,16 @@ #include "goodix_proto.h" #include "goodix511.h" +#include + +#define GOODIX511_WIDTH 88 +#define GOODIX511_HEIGHT 80 +#define GOODIX511_FRAME_SIZE 80 * 88 +// For every 4 pixels there are 6 bytes and there are 8 extra start bytes and 5 +// extra end +#define GOODIX511_RAW_FRAME_SIZE 8 + GOODIX511_FRAME_SIZE / 4 * 6 + 5 +#define GOODIX511_CAP_FRAMES 3 // Number of frames we capture per swipe + struct _FpiDeviceGoodixTls511 { FpiDeviceGoodixTls parent; @@ -47,8 +57,6 @@ struct _FpiDeviceGoodixTls511 { GSList* frames; }; -#define GOODIXTLS_CAP_FRAMES 1 - G_DECLARE_FINAL_TYPE(FpiDeviceGoodixTls511, fpi_device_goodixtls511, FPI, DEVICE_GOODIXTLS511, FpiDeviceGoodixTls); @@ -376,31 +384,6 @@ static void check_none_cmd(FpDevice* dev, guint8* data, guint16 len, fpi_ssm_next_state(ssm); } -static void write_pgm(guint8* data, guint16 len) -{ - g_assert(len != 0); - int needed = len / 6 * 4; - int* img = malloc(sizeof(int) * needed); - int* head = img; - for (int i = 0; i < len; i += 6) { - guint8* chunk = data + i; - *head++ = ((chunk[0] & 0xf) << 8) + chunk[1]; - *head++ = ((chunk[3] << 4) + (chunk[0] >> 4)); - *head++ = ((chunk[5] & 0xf) << 8) + chunk[2]; - *head++ = ((chunk[4] << 4) + (chunk[5] >> 4)); - } - FILE* out = fopen("./fingerprint.pgm", "w"); - const char buff[] = "P2\n88 80\n4095\n"; - fwrite(buff, sizeof(char), sizeof(buff), out); - int count = 0; - for (int* line = img; count < needed; line += 4) { - fwrite(line, sizeof(int), 4, out); - fwrite("\n", sizeof(char), 1, out); - count += 4; - } - fclose(out); - free(img); -} static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, struct fpi_frame* frame, unsigned int x, unsigned int y) @@ -408,36 +391,25 @@ static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, return frame->data[x + y * ctx->frame_width]; } -#define GOODIX511_WIDTH 80 -#define GOODIX511_HEIGHT 88 -#define GOODIX511_FRAME_SIZE 80 * 88 -#define GOODIX511_RAW_FRAME_SIZE \ - GOODIX511_FRAME_SIZE / 4 * 6 // For every 4 pixels there are 6 bytes +// Bitdepth is 12, but we have to fit it in a byte +static unsigned char squash(int v) { return v / 16; } static void decode_frame(guint8* raw_frame, GSList** frames) { - const int frame_size = GOODIX511_FRAME_SIZE; + const int frame_size = GOODIX511_FRAME_SIZE * 2; struct fpi_frame* frame = g_malloc(frame_size + sizeof(struct fpi_frame)); - raw_frame += 8; guint8* pix = frame->data; - for (int i = 0; i < GOODIX511_RAW_FRAME_SIZE; i += 6) { + for (int i = 8; i != GOODIX511_RAW_FRAME_SIZE - 5; i += 6) { guint8* chunk = raw_frame + i; - *pix++ = ((chunk[0] & 0xf) << 8) + chunk[1]; - *pix++ = ((chunk[3] << 4) + (chunk[0] >> 4)); - *pix++ = ((chunk[5] & 0xf) << 8) + chunk[2]; - *pix++ = ((chunk[4] << 4) + (chunk[5] >> 4)); + *pix++ = squash(((chunk[0] & 0xf) << 8) + chunk[1]); + *pix++ = squash((chunk[3] << 4) + (chunk[0] >> 4)); + *pix++ = squash(((chunk[5] & 0xf) << 8) + chunk[2]); + *pix++ = squash((chunk[4] << 4) + (chunk[5] >> 4)); } *frames = g_slist_append(*frames, frame); } -static void write_frame(guint8* frame, GSList** frames) -{ - FILE* out = fopen("./fingerprint.pgm", "w"); - const char buff[] = "P2\n88 80\n4095\n"; - fwrite(buff, sizeof(char), sizeof(buff), out); - fwrite(frame, sizeof(guint8), GOODIX511_FRAME_SIZE, out); - fclose(out); -} + static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, gpointer ssm, GError* err) { @@ -447,13 +419,7 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, } FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); if (fpi_ssm_get_cur_state(ssm) == SCAN_STAGE_GET_IMG_1) { - if (g_slist_length(self->frames) <= 3) { - /*GSList* frame = NULL; - // decode_frame(data, &frame); - FILE* f = fopen("./fingerraw.bin", "wb"); - fwrite(data, sizeof(guint8), len, f); - fclose(f); - // write_frame(g_slist_nth_data(frame, 0), NULL);*/ + if (g_slist_length(self->frames) <= GOODIX511_CAP_FRAMES) { self->frames = g_slist_append(self->frames, data); fpi_ssm_jump_to_state(ssm, SCAN_STAGE_SWITCH_TO_FDT_MODE_2); return; @@ -464,18 +430,15 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); struct fpi_frame_asmbl_ctx assembly_ctx; - assembly_ctx.frame_width = 80; - assembly_ctx.frame_height = 86; - assembly_ctx.image_width = 80 * 3 / 2; + assembly_ctx.frame_width = GOODIX511_WIDTH; + assembly_ctx.frame_height = GOODIX511_HEIGHT; + assembly_ctx.image_width = GOODIX511_WIDTH; assembly_ctx.get_pixel = get_pix; GSList* frames = NULL; g_slist_foreach(raw_frames, (GFunc) decode_frame, &frames); - // g_slist_foreach(g_slist_nth(frames, 1), (GFunc) write_frame, - // NULL); - // write_pgm(data, len); fpi_do_movement_estimation(&assembly_ctx, frames); FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); img->flags |= FPI_IMAGE_PARTIAL; @@ -650,8 +613,8 @@ static void fpi_device_goodixtls511_class_init( // TODO img_dev_class->bz3_threshold = 24; - img_dev_class->img_width = 80; - img_dev_class->img_height = 88; + img_dev_class->img_width = GOODIX511_WIDTH; + img_dev_class->img_height = GOODIX511_HEIGHT; img_dev_class->img_open = dev_init; img_dev_class->img_close = dev_deinit; From 416eadf1f488124c35ca26f3a737fc29ba307071 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 22:08:27 +0100 Subject: [PATCH 18/57] chore: cleanup --- libfprint/drivers/goodixtls/goodix.c | 43 ++----------------- libfprint/drivers/goodixtls/goodix511.c | 56 ++++++++++--------------- 2 files changed, 24 insertions(+), 75 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 44317eadd..a55922167 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -43,7 +43,6 @@ typedef struct { gboolean ack; gboolean reply; - gboolean tls; GoodixCmdCallback callback; gpointer user_data; @@ -318,35 +317,6 @@ void goodix_receive_protocol(FpDevice *dev, guint8 *data, guint32 length) { goodix_receive_done(dev, payload, payload_len, NULL); } -static void goodix_receive_tls(FpDevice* dev, guint8* data, guint32 length) -{ - FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); - FpiDeviceGoodixTlsPrivate* priv = - fpi_device_goodixtls_get_instance_private(self); - g_autofree guint8* payload = NULL; - guint16 payload_len; - gboolean valid_checksum; // TODO implement checksum. - guint8 flags; - - if (!goodix_decode_pack(data, length, &flags, &payload, &payload_len, - &valid_checksum)) { - fp_err("Incomplete, size tls: %d", length); - // Protocol is not full, we still need data. - // TODO implement protocol assembling. - return; - } - - if (!priv->reply) { - fp_warn("Didn't excpect a reply for command: 0x%02x", priv->cmd); - return; - } - - if (priv->ack) - fp_warn("Didn't got ACK for command: 0x%02x", priv->cmd); - - goodix_receive_done(dev, payload, payload_len, NULL); -} - void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { FpiDeviceGoodixTls *self = FPI_DEVICE_GOODIXTLS(dev); FpiDeviceGoodixTlsPrivate *priv = @@ -375,9 +345,6 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { case GOODIX_FLAGS_TLS: fp_dbg("Got TLS msg"); - if (!priv->tls) { - fp_warn("unexpected tls packet"); - } goodix_receive_done(dev, payload, payload_len, NULL); // TLS message sending it to TLS server. @@ -439,9 +406,9 @@ void goodix_receive_data(FpDevice *dev) { // ---- GOODIX SEND SECTION START ---- -gboolean goodix_send_data(FpDevice *dev, guint8 *data, guint32 length, - GDestroyNotify free_func, GError **error) { - fp_dbg("--- SEND DATA SIZE: %d ---", length); +gboolean goodix_send_data(FpDevice* dev, guint8* data, guint32 length, + GDestroyNotify free_func, GError** error) +{ FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); FpiDeviceGoodixTlsClass* class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); @@ -1112,7 +1079,6 @@ enum goodix_tls_handshake_stages { static void on_tls_successfully_established(FpDevice* dev, gpointer user_data, GError* error) { - fp_dbg("HANDSHAKE DONE"); FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); FpiDeviceGoodixTlsPrivate* priv = @@ -1275,9 +1241,6 @@ void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, gpointer user_data) { g_assert(callback); - FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); - FpiDeviceGoodixTlsPrivate* priv = - fpi_device_goodixtls_get_instance_private(self); GoodixCallbackInfo* cb_info = malloc(sizeof(GoodixImageCallback)); cb_info->callback = G_CALLBACK(callback); diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index b9625ec39..118ea63b8 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -52,7 +52,6 @@ struct _FpiDeviceGoodixTls511 { FpiDeviceGoodixTls parent; guint8* otp; - guint16 otp_len; GSList* frames; }; @@ -178,7 +177,6 @@ static void check_preset_psk_read(FpDevice *dev, gboolean success, } static void check_idle(FpDevice* dev, gpointer user_data, GError* err) { - G_DEBUG_HERE(); if (err) { fpi_ssm_mark_failed(user_data, err); @@ -189,14 +187,13 @@ static void check_idle(FpDevice* dev, gpointer user_data, GError* err) static void check_config_upload(FpDevice* dev, gboolean success, gpointer user_data, GError* error) { - G_DEBUG_HERE(); if (error) { fpi_ssm_mark_failed(user_data, error); } else if (!success) { - GError* err = malloc(sizeof(GError)); - err->message = "Failed to upload config"; - fpi_ssm_mark_failed(user_data, err); + fpi_ssm_mark_failed(user_data, + g_error_new(FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO, + "failed to upload mcu config")); } else { fpi_ssm_next_state(user_data); @@ -209,9 +206,9 @@ static void check_powerdown_scan_freq(FpDevice* dev, gboolean success, fpi_ssm_mark_failed(user_data, error); } else if (!success) { - GError* err = malloc(sizeof(GError)); - err->message = "Failed set powerdown"; - fpi_ssm_mark_failed(user_data, err); + fpi_ssm_mark_failed(user_data, + g_error_new(FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO, + "failed to set powerdown freq")); } else { fpi_ssm_next_state(user_data); @@ -254,7 +251,6 @@ static void otp_write_run(FpiSsm* ssm, FpDevice* dev) ssm); if (fpi_ssm_get_cur_state(ssm) == OTP_WRITE_NUM - 1) { free(self->otp); - self->otp_len = 0; } } @@ -274,22 +270,17 @@ static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); self->otp = malloc(len); memcpy(self->otp, data, len); - self->otp_len = len; FpiSsm* otp_ssm = fpi_ssm_new(dev, otp_write_run, OTP_WRITE_NUM); fpi_ssm_start_subsm(ssm, otp_ssm); } -static void activate_run_state(FpiSsm *ssm, FpDevice *dev) { - GError *error = NULL; +static void activate_run_state(FpiSsm* ssm, FpDevice* dev) +{ - switch (fpi_ssm_get_cur_state(ssm)) { + switch (fpi_ssm_get_cur_state(ssm)) { case ACTIVATE_READ_AND_NOP: - /* Uncomment below in case the successfully established bit didn't get - run and you get a timeout when trying to rerun */ - // goodix_send_tls_successfully_established(dev, NULL, NULL); - // exit(0); - // Nop seems to clear the previous command buffer. But we are - // unable to do so. + // Nop seems to clear the previous command buffer. But we are + // unable to do so. goodix_receive_data(dev); goodix_send_nop(dev, check_none, ssm); break; @@ -473,13 +464,8 @@ const guint8 fdt_switch_state_down[] = { 0xa4, 0x80, 0xb8, 0x80, 0xa8, 0x80, 0xb7, }; -const guint8 fdt_switch_state_down_1[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, - 0xbf, 0x80, 0xa4, 0x80, 0xb8, - 0x80, 0xa8, 0x80, 0xb7}; - static void scan_run_state(FpiSsm* ssm, FpDevice* dev) { - FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); switch (fpi_ssm_get_cur_state(ssm)) { case SCAN_STAGE_QUERY_MCU: @@ -487,26 +473,26 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) break; case SCAN_STAGE_SWITCH_TO_FDT_MODE_0: - goodix_send_mcu_switch_to_fdt_mode(dev, fdt_switch_state_mode_0, - sizeof(fdt_switch_state_mode_0), - NULL, check_none_cmd, ssm); + goodix_send_mcu_switch_to_fdt_mode( + dev, (guint8*) fdt_switch_state_mode_0, + sizeof(fdt_switch_state_mode_0), NULL, check_none_cmd, ssm); break; case SCAN_STAGE_NAV_0: goodix_send_nav_0(dev, check_none_cmd, ssm); break; case SCAN_STAGE_SWITCH_TO_FDT_MODE_1: - goodix_send_mcu_switch_to_fdt_mode(dev, fdt_switch_state_mode_1, - sizeof(fdt_switch_state_mode_1), - NULL, check_none_cmd, ssm); + goodix_send_mcu_switch_to_fdt_mode( + dev, (guint8*) fdt_switch_state_mode_1, + sizeof(fdt_switch_state_mode_1), NULL, check_none_cmd, ssm); break; case SCAN_STAGE_SWITCH_TO_FDT_MODE_2: - goodix_send_mcu_switch_to_fdt_mode(dev, fdt_switch_state_mode_2, - sizeof(fdt_switch_state_mode_2), - NULL, check_none_cmd, ssm); + goodix_send_mcu_switch_to_fdt_mode( + dev, (guint8*) fdt_switch_state_mode_2, + sizeof(fdt_switch_state_mode_2), NULL, check_none_cmd, ssm); break; case SCAN_STAGE_SWITCH_TO_FDT_DOWN: - goodix_send_mcu_switch_to_fdt_down(dev, fdt_switch_state_down, + goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down, sizeof(fdt_switch_state_down), NULL, check_none_cmd, ssm); break; From cfa1cbc986d21f158b8683bb7f3266dcd427ff18 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 22:52:34 +0100 Subject: [PATCH 19/57] fix: possible invalid access --- libfprint/drivers/goodixtls/goodix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index a55922167..0f7943603 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -1241,7 +1241,7 @@ void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, gpointer user_data) { g_assert(callback); - GoodixCallbackInfo* cb_info = malloc(sizeof(GoodixImageCallback)); + GoodixCallbackInfo* cb_info = malloc(sizeof(GoodixCallbackInfo)); cb_info->callback = G_CALLBACK(callback); cb_info->user_data = user_data; From 06c891a6a099dcfb74eeb655575cd966c48d390f Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 23:12:09 +0100 Subject: [PATCH 20/57] chore: major cleanup Turns out we don't need a bunch of steps in the capture process --- libfprint/drivers/goodixtls/goodix511.c | 111 +++++++++--------------- 1 file changed, 39 insertions(+), 72 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 118ea63b8..804f738fe 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -352,15 +352,9 @@ static void activate_complete(FpiSsm* ssm, FpDevice* dev, GError* error) // ---- SCAN SECTION START ---- enum SCAN_STAGES { - SCAN_STAGE_QUERY_MCU, - SCAN_STAGE_SWITCH_TO_FDT_MODE_0, - SCAN_STAGE_NAV_0, - SCAN_STAGE_SWITCH_TO_FDT_MODE_1, - SCAN_STAGE_READ_REG, - SCAN_STAGE_GET_IMG_0, - SCAN_STAGE_SWITCH_TO_FDT_MODE_2, + SCAN_STAGE_SWITCH_TO_FDT_MODE, SCAN_STAGE_SWITCH_TO_FDT_DOWN, - SCAN_STAGE_GET_IMG_1, + SCAN_STAGE_GET_IMG, SCAN_STAGE_NUM, }; @@ -408,56 +402,49 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, fpi_ssm_mark_failed(ssm, err); return; } + FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); - if (fpi_ssm_get_cur_state(ssm) == SCAN_STAGE_GET_IMG_1) { - if (g_slist_length(self->frames) <= GOODIX511_CAP_FRAMES) { - self->frames = g_slist_append(self->frames, data); - fpi_ssm_jump_to_state(ssm, SCAN_STAGE_SWITCH_TO_FDT_MODE_2); - return; - } - else { - self->frames = g_slist_append(self->frames, data); - GSList* raw_frames = g_slist_nth(self->frames, 1); - - FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); - struct fpi_frame_asmbl_ctx assembly_ctx; - assembly_ctx.frame_width = GOODIX511_WIDTH; - assembly_ctx.frame_height = GOODIX511_HEIGHT; - assembly_ctx.image_width = GOODIX511_WIDTH; - assembly_ctx.get_pixel = get_pix; - - GSList* frames = NULL; - - g_slist_foreach(raw_frames, (GFunc) decode_frame, &frames); - - fpi_do_movement_estimation(&assembly_ctx, frames); - FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); - img->flags |= FPI_IMAGE_PARTIAL; - - g_slist_free_full(frames, g_free); - - fpi_image_device_image_captured(img_dev, img); - fpi_image_device_report_finger_status(img_dev, FALSE); - } + if (g_slist_length(self->frames) <= GOODIX511_CAP_FRAMES) { + self->frames = g_slist_append(self->frames, data); + fpi_ssm_jump_to_state(ssm, SCAN_STAGE_SWITCH_TO_FDT_MODE); } + else { + self->frames = g_slist_append(self->frames, data); + GSList* raw_frames = g_slist_nth(self->frames, 1); - fpi_ssm_next_state(ssm); + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + struct fpi_frame_asmbl_ctx assembly_ctx; + assembly_ctx.frame_width = GOODIX511_WIDTH; + assembly_ctx.frame_height = GOODIX511_HEIGHT; + assembly_ctx.image_width = GOODIX511_WIDTH; + assembly_ctx.get_pixel = get_pix; + + GSList* frames = NULL; + + g_slist_foreach(raw_frames, (GFunc) decode_frame, &frames); + + fpi_do_movement_estimation(&assembly_ctx, frames); + FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); + img->flags |= FPI_IMAGE_PARTIAL; + + g_slist_free_full(frames, g_free); + + fpi_image_device_image_captured(img_dev, img); + fpi_image_device_report_finger_status(img_dev, FALSE); + + fpi_ssm_next_state(ssm); + } } static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { goodix_tls_read_image(dev, scan_on_read_img, ssm); } -const guint8 fdt_switch_state_mode_2[] = { + +const guint8 fdt_switch_state_mode[] = { 0x0d, 0x01, 0x80, 0xaf, 0x80, 0xbf, 0x80, 0xa4, 0x80, 0xb8, 0x80, 0xa8, 0x80, 0xb7, }; -const guint8 fdt_switch_state_mode_0[] = {0x0d, 0x01, 0xae, 0xae, 0xbf, - 0xbf, 0xa4, 0xa4, 0xb8, 0xb8, - 0xa8, 0xa8, 0xb7, 0xb7}; -const guint8 fdt_switch_state_mode_1[] = {0x0d, 0x01, 0x80, 0xaf, 0x80, 0xbf, - 0x80, 0xa3, 0x0d, 0x01, 0x80, 0xaf, - 0x80, 0xbf, 0x80, 0xa3}; const guint8 fdt_switch_state_down[] = { 0x0c, 0x01, 0x80, 0xaf, 0x80, 0xbf, 0x80, @@ -467,28 +454,12 @@ const guint8 fdt_switch_state_down[] = { static void scan_run_state(FpiSsm* ssm, FpDevice* dev) { FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); - switch (fpi_ssm_get_cur_state(ssm)) { - case SCAN_STAGE_QUERY_MCU: - goodix_send_query_mcu_state(dev, check_none_cmd, ssm); - break; - case SCAN_STAGE_SWITCH_TO_FDT_MODE_0: - goodix_send_mcu_switch_to_fdt_mode( - dev, (guint8*) fdt_switch_state_mode_0, - sizeof(fdt_switch_state_mode_0), NULL, check_none_cmd, ssm); - break; - case SCAN_STAGE_NAV_0: - goodix_send_nav_0(dev, check_none_cmd, ssm); - break; - case SCAN_STAGE_SWITCH_TO_FDT_MODE_1: - goodix_send_mcu_switch_to_fdt_mode( - dev, (guint8*) fdt_switch_state_mode_1, - sizeof(fdt_switch_state_mode_1), NULL, check_none_cmd, ssm); - break; - case SCAN_STAGE_SWITCH_TO_FDT_MODE_2: - goodix_send_mcu_switch_to_fdt_mode( - dev, (guint8*) fdt_switch_state_mode_2, - sizeof(fdt_switch_state_mode_2), NULL, check_none_cmd, ssm); + switch (fpi_ssm_get_cur_state(ssm)) { + case SCAN_STAGE_SWITCH_TO_FDT_MODE: + goodix_send_mcu_switch_to_fdt_mode(dev, (guint8*) fdt_switch_state_mode, + sizeof(fdt_switch_state_mode), NULL, + check_none_cmd, ssm); break; case SCAN_STAGE_SWITCH_TO_FDT_DOWN: @@ -496,14 +467,10 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) sizeof(fdt_switch_state_down), NULL, check_none_cmd, ssm); break; - case SCAN_STAGE_GET_IMG_1: + case SCAN_STAGE_GET_IMG: fpi_image_device_report_finger_status(img_dev, TRUE); - case SCAN_STAGE_GET_IMG_0: scan_get_img(dev, ssm); break; - case SCAN_STAGE_READ_REG: - goodix_send_read_sensor_register(dev, 0x0082, 2, check_none_cmd, ssm); - break; } } From 635732290490ddae926031ad91a471dbd6e74ead Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Sun, 5 Sep 2021 23:28:32 +0100 Subject: [PATCH 21/57] fix: lockup if failure during activation --- libfprint/drivers/goodixtls/goodix511.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 804f738fe..dbead16ce 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -343,6 +343,11 @@ static void activate_complete(FpiSsm* ssm, FpDevice* dev, GError* error) G_DEBUG_HERE(); if (!error) goodix_tls(dev, tls_activation_complete, NULL); + else { + fp_err("failed during activation: %s (code: %d)", error->message, + error->code); + fpi_image_device_activate_complete(FP_IMAGE_DEVICE(dev), error); + } } // ---- ACTIVE SECTION END ---- From 999955e6a7b0c0ab0cccf70ae0ad5708a1837973 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Mon, 6 Sep 2021 11:52:44 +0100 Subject: [PATCH 22/57] feat: reenable verification --- libfprint/drivers/goodixtls/goodix511.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index dbead16ce..73ff1feb8 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -581,5 +581,4 @@ static void fpi_device_goodixtls511_class_init( img_dev_class->deactivate = dev_deactivate; fpi_device_class_auto_initialize_features(dev_class); - dev_class->features &= ~FP_DEVICE_FEATURE_VERIFY; } From 2431ff997182b2e9b515bead14e0ffd3d1ad427a Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Mon, 6 Sep 2021 12:20:45 +0100 Subject: [PATCH 23/57] fix: non-graceful shutdown of usb transfer --- libfprint/drivers/goodixtls/goodix.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 0f7943603..cc6c367ff 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -51,6 +51,8 @@ typedef struct { guint32 length; GoodixCallbackInfo* tls_ready_callback; + + GCancellable* transfer_cancel_tkn; } FpiDeviceGoodixTlsPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(FpiDeviceGoodixTls, fpi_device_goodixtls, @@ -392,12 +394,15 @@ void goodix_receive_data(FpDevice *dev) { FpiDeviceGoodixTls *self = FPI_DEVICE_GOODIXTLS(dev); FpiDeviceGoodixTlsClass *class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); transfer->short_is_error = FALSE; fpi_usb_transfer_fill_bulk(transfer, class->ep_in, GOODIX_EP_IN_MAX_BUF_SIZE); - fpi_usb_transfer_submit(transfer, 0, NULL, goodix_receive_data_cb, NULL); + fpi_usb_transfer_submit(transfer, 0, priv->transfer_cancel_tkn, + goodix_receive_data_cb, NULL); } // ---- GOODIX RECEIVE SECTION END ---- @@ -986,6 +991,7 @@ gboolean goodix_dev_init(FpDevice *dev, GError **error) { priv->user_data = NULL; priv->data = NULL; priv->length = 0; + priv->transfer_cancel_tkn = g_cancellable_new(); return g_usb_device_claim_interface(fpi_device_get_usb_device(dev), class->interface, 0, error); @@ -999,6 +1005,7 @@ gboolean goodix_dev_deinit(FpDevice *dev, GError **error) { if (priv->timeout) g_source_destroy(priv->timeout); g_free(priv->data); + g_cancellable_cancel(priv->transfer_cancel_tkn); return g_usb_device_release_interface(fpi_device_get_usb_device(dev), class->interface, 0, error); From b5cfe0549e4cd6d92c3fc4e6fb508eb00c38a3c8 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Mon, 6 Sep 2021 12:34:55 +0100 Subject: [PATCH 24/57] fix: operation cancelled before start --- libfprint/drivers/goodixtls/goodix.c | 134 ++++++++++++++---------- libfprint/drivers/goodixtls/goodix.h | 2 + libfprint/drivers/goodixtls/goodix511.c | 2 +- 3 files changed, 80 insertions(+), 58 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index cc6c367ff..d6ac5e533 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -17,6 +17,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include "fpi-log.h" #include "fpi-ssm.h" #include "fpi-usb-transfer.h" #define FP_COMPONENT "goodixtls" @@ -390,19 +391,34 @@ void goodix_receive_timeout_cb(FpDevice *dev, gpointer user_data) { goodix_receive_done(dev, NULL, 0, error); } -void goodix_receive_data(FpDevice *dev) { - FpiDeviceGoodixTls *self = FPI_DEVICE_GOODIXTLS(dev); - FpiDeviceGoodixTlsClass *class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); - FpiUsbTransfer *transfer = fpi_usb_transfer_new(dev); - FpiDeviceGoodixTlsPrivate* priv = - fpi_device_goodixtls_get_instance_private(self); +void goodix_start_read_loop(FpDevice* dev) +{ + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + + if (g_cancellable_is_cancelled(priv->transfer_cancel_tkn)) { + g_cancellable_reset(priv->transfer_cancel_tkn); + } + + goodix_receive_data(dev); +} + +void goodix_receive_data(FpDevice * dev) +{ + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsClass* class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); + FpiUsbTransfer* transfer = fpi_usb_transfer_new(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); - transfer->short_is_error = FALSE; + transfer->short_is_error = FALSE; - fpi_usb_transfer_fill_bulk(transfer, class->ep_in, GOODIX_EP_IN_MAX_BUF_SIZE); + fpi_usb_transfer_fill_bulk(transfer, class->ep_in, + GOODIX_EP_IN_MAX_BUF_SIZE); - fpi_usb_transfer_submit(transfer, 0, priv->transfer_cancel_tkn, - goodix_receive_data_cb, NULL); + fpi_usb_transfer_submit(transfer, 0, priv->transfer_cancel_tkn, + goodix_receive_data_cb, NULL); } // ---- GOODIX RECEIVE SECTION END ---- @@ -411,8 +427,8 @@ void goodix_receive_data(FpDevice *dev) { // ---- GOODIX SEND SECTION START ---- -gboolean goodix_send_data(FpDevice* dev, guint8* data, guint32 length, - GDestroyNotify free_func, GError** error) +gboolean goodix_send_data(FpDevice * dev, guint8 * data, guint32 length, + GDestroyNotify free_func, GError * *error) { FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); FpiDeviceGoodixTlsClass* class = FPI_DEVICE_GOODIXTLS_GET_CLASS(self); @@ -424,73 +440,77 @@ gboolean goodix_send_data(FpDevice* dev, guint8* data, guint32 length, fpi_usb_transfer_fill_bulk_full(transfer, class->ep_out, data + i, GOODIX_EP_OUT_MAX_BUF_SIZE, NULL); - if (!fpi_usb_transfer_submit_sync(transfer, GOODIX_TIMEOUT, error)) { + if (!fpi_usb_transfer_submit_sync(transfer, GOODIX_TIMEOUT, + error)) { if (free_func) free_func(data); fpi_usb_transfer_unref(transfer); return FALSE; } fpi_usb_transfer_unref(transfer); - } + } - if (free_func) - free_func(data); - return TRUE; + if (free_func) + free_func(data); + return TRUE; } -gboolean goodix_send_pack(FpDevice *dev, guint8 flags, guint8 *payload, +gboolean goodix_send_pack(FpDevice * dev, guint8 flags, guint8 * payload, guint16 length, GDestroyNotify free_func, - GError **error) { - guint8 *data; - guint32 data_len; + GError * *error) +{ + guint8* data; + guint32 data_len; - goodix_encode_pack(flags, payload, length, TRUE, &data, &data_len); - if (free_func) free_func(payload); + goodix_encode_pack(flags, payload, length, TRUE, &data, &data_len); + if (free_func) + free_func(payload); - return goodix_send_data(dev, data, data_len, g_free, error); + return goodix_send_data(dev, data, data_len, g_free, error); } -void goodix_send_protocol(FpDevice *dev, guint8 cmd, guint8 *payload, - guint16 length, GDestroyNotify free_func, - gboolean calc_checksum, guint timeout_ms, - gboolean reply, GoodixCmdCallback callback, - gpointer user_data) { - FpiDeviceGoodixTls *self = FPI_DEVICE_GOODIXTLS(dev); - FpiDeviceGoodixTlsPrivate *priv = +void goodix_send_protocol( + FpDevice * dev, guint8 cmd, guint8 * payload, guint16 length, + GDestroyNotify free_func, gboolean calc_checksum, guint timeout_ms, + gboolean reply, GoodixCmdCallback callback, gpointer user_data) + { + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); - GError *error = NULL; - guint8 *data; + GError* error = NULL; + guint8* data; guint32 data_len; - if (priv->ack || priv->reply || priv->timeout) { - // A command is already running. - fp_warn("A command is already running: 0x%02x", priv->cmd); - if (free_func) free_func(payload); - return; - } + if (priv->ack || priv->reply || priv->timeout) { + // A command is already running. + fp_warn("A command is already running: 0x%02x", priv->cmd); + if (free_func) + free_func(payload); + return; + } - fp_dbg("Running command: 0x%02x", cmd); + fp_dbg("Running command: 0x%02x", cmd); - if (timeout_ms) - priv->timeout = fpi_device_add_timeout( - dev, timeout_ms, goodix_receive_timeout_cb, NULL, NULL); - priv->cmd = cmd; - priv->ack = TRUE; - priv->reply = reply; - priv->callback = callback; - priv->user_data = user_data; + if (timeout_ms) + priv->timeout = fpi_device_add_timeout( + dev, timeout_ms, goodix_receive_timeout_cb, NULL, NULL); + priv->cmd = cmd; + priv->ack = TRUE; + priv->reply = reply; + priv->callback = callback; + priv->user_data = user_data; - goodix_encode_protocol(cmd, payload, length, calc_checksum, FALSE, &data, - &data_len); - if (free_func) free_func(payload); + goodix_encode_protocol(cmd, payload, length, calc_checksum, FALSE, + &data, &data_len); + if (free_func) + free_func(payload); - if (!goodix_send_pack(dev, GOODIX_FLAGS_MSG_PROTOCOL, data, data_len, g_free, - &error)) { - goodix_receive_done(dev, NULL, 0, error); - return; - }; + if (!goodix_send_pack(dev, GOODIX_FLAGS_MSG_PROTOCOL, data, data_len, + g_free, &error)) { + goodix_receive_done(dev, NULL, 0, error); + return; + }; } - void goodix_send_nop(FpDevice *dev, GoodixNoneCallback callback, gpointer user_data) { GoodixNop payload = {.unknown = 0x00000000}; diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index 6d0f55a27..8c17278a4 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -114,6 +114,7 @@ void goodix_receive_timeout_cb(FpDevice *dev, gpointer user_data); void goodix_receive_data(FpDevice *dev); +void goodix_start_read_loop(FpDevice* dev); // ---- GOODIX RECEIVE SECTION END ---- // ----------------------------------------------------------------------------- @@ -226,6 +227,7 @@ gboolean goodix_dev_init(FpDevice *dev, GError **error); gboolean goodix_dev_deinit(FpDevice *dev, GError **error); + // ---- DEV SECTION END ---- // ----------------------------------------------------------------------------- diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 73ff1feb8..f5fff36fd 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -281,7 +281,7 @@ static void activate_run_state(FpiSsm* ssm, FpDevice* dev) case ACTIVATE_READ_AND_NOP: // Nop seems to clear the previous command buffer. But we are // unable to do so. - goodix_receive_data(dev); + goodix_start_read_loop(dev); goodix_send_nop(dev, check_none, ssm); break; From b327b0b5a14f1a4799780a25cc06a9b58b2217dd Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Mon, 6 Sep 2021 13:43:18 +0100 Subject: [PATCH 25/57] fix: operation cancelled before start --- libfprint/drivers/goodixtls/goodix.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index d6ac5e533..32efff403 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -365,6 +365,14 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { void goodix_receive_data_cb(FpiUsbTransfer *transfer, FpDevice *dev, gpointer user_data, GError *error) { + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + + if (g_cancellable_is_cancelled(priv->transfer_cancel_tkn)) { + fp_dbg("transfer cancelled, aborting read loop..."); + return; + } if (error) { // Warn about error and free it. fp_warn("Receive data error: %s", error->message); From 58d878f18bbbc31b05648a885f360df6e4d0d2af Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Mon, 6 Sep 2021 14:55:42 +0100 Subject: [PATCH 26/57] feat: works with fprintd This has a few misc fixes and changes to the shutdown code --- libfprint/drivers/goodixtls/goodix.c | 52 ++++++++++++++++++++----- libfprint/drivers/goodixtls/goodix.h | 3 ++ libfprint/drivers/goodixtls/goodix511.c | 13 +++++-- libfprint/drivers/goodixtls/goodixtls.c | 8 ++-- 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 32efff403..85c992005 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -54,6 +54,7 @@ typedef struct { GoodixCallbackInfo* tls_ready_callback; GCancellable* transfer_cancel_tkn; + gboolean inited; } FpiDeviceGoodixTlsPrivate; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(FpiDeviceGoodixTls, fpi_device_goodixtls, @@ -82,12 +83,7 @@ void goodix_receive_done(FpDevice *dev, guint8 *data, guint16 length, if (!(priv->ack || priv->reply)) return; - if (priv->timeout) g_clear_pointer(&priv->timeout, g_source_destroy); - priv->ack = FALSE; - priv->reply = FALSE; - priv->callback = NULL; - priv->user_data = NULL; - + goodix_reset_state(dev); if (!error) fp_dbg("Completed command: 0x%02x", priv->cmd); if (callback) callback(dev, data, length, user_data, error); @@ -405,6 +401,13 @@ void goodix_start_read_loop(FpDevice* dev) FpiDeviceGoodixTlsPrivate* priv = fpi_device_goodixtls_get_instance_private(self); + if (priv->inited) { + // Already going + return; + } + else { + priv->inited = TRUE; + } if (g_cancellable_is_cancelled(priv->transfer_cancel_tkn)) { g_cancellable_reset(priv->transfer_cancel_tkn); } @@ -887,9 +890,8 @@ void goodix_send_request_tls_connection(FpDevice* dev, cb_info->user_data = user_data; goodix_send_protocol(dev, GOODIX_CMD_REQUEST_TLS_CONNECTION, - (guint8*) &payload, sizeof(payload), NULL, TRUE, - GOODIX_TIMEOUT, TRUE, goodix_receive_default, - cb_info); + (guint8*) &payload, sizeof(payload), NULL, TRUE, 0, + TRUE, goodix_receive_default, cb_info); return; } @@ -1024,6 +1026,19 @@ gboolean goodix_dev_init(FpDevice *dev, GError **error) { return g_usb_device_claim_interface(fpi_device_get_usb_device(dev), class->interface, 0, error); } +void goodix_reset_state(FpDevice* dev) +{ + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + + if (priv->timeout) + g_clear_pointer(&priv->timeout, g_source_destroy); + priv->ack = FALSE; + priv->reply = FALSE; + priv->callback = NULL; + priv->user_data = NULL; +} gboolean goodix_dev_deinit(FpDevice *dev, GError **error) { FpiDeviceGoodixTls *self = FPI_DEVICE_GOODIXTLS(dev); @@ -1034,6 +1049,10 @@ gboolean goodix_dev_deinit(FpDevice *dev, GError **error) { if (priv->timeout) g_source_destroy(priv->timeout); g_free(priv->data); g_cancellable_cancel(priv->transfer_cancel_tkn); + goodix_shutdown_tls(dev, error); + + goodix_reset_state(dev); + priv->inited = FALSE; return g_usb_device_release_interface(fpi_device_get_usb_device(dev), class->interface, 0, error); @@ -1244,6 +1263,21 @@ void goodix_tls(FpDevice* dev, GoodixNoneCallback callback, gpointer user_data) goodix_tls_ready(s, err, self); } + +gboolean goodix_shutdown_tls(FpDevice* dev, GError** error) +{ + FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); + FpiDeviceGoodixTlsPrivate* priv = + fpi_device_goodixtls_get_instance_private(self); + + if (priv->tls_hop) { + gboolean rs = goodix_tls_server_deinit(priv->tls_hop, error); + g_free(priv->tls_hop); + priv->tls_hop = NULL; + return rs; + } + return TRUE; +} static void goodix_tls_ready_image_handler(FpDevice* dev, guint8* data, guint16 length, gpointer user_data, GError* error) diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index 8c17278a4..f4f8456ad 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -227,6 +227,7 @@ gboolean goodix_dev_init(FpDevice *dev, GError **error); gboolean goodix_dev_deinit(FpDevice *dev, GError **error); +void goodix_reset_state(FpDevice* dev); // ---- DEV SECTION END ---- @@ -243,6 +244,8 @@ void goodix_tls_complete(FpiSsm *ssm, FpDevice *dev, GError *error); void goodix_tls(FpDevice* dev, GoodixNoneCallback callback, gpointer user_data); +gboolean goodix_shutdown_tls(FpDevice* dev, GError** error); + void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, gpointer user_data); diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index f5fff36fd..50557df15 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -443,6 +443,7 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { + g_object_ref(fpi_ssm_get_device(ssm)); goodix_tls_read_image(dev, scan_on_read_img, ssm); } @@ -523,10 +524,10 @@ static void dev_deinit(FpImageDevice *img_dev) { } static void dev_activate(FpImageDevice *img_dev) { - FpDevice *dev = FP_DEVICE(img_dev); + FpDevice* dev = FP_DEVICE(img_dev); - fpi_ssm_start(fpi_ssm_new(dev, activate_run_state, ACTIVATE_NUM_STATES), - activate_complete); + fpi_ssm_start(fpi_ssm_new(dev, activate_run_state, ACTIVATE_NUM_STATES), + activate_complete); } @@ -542,7 +543,11 @@ static void dev_change_state(FpImageDevice* img_dev, FpiImageDeviceState state) } static void dev_deactivate(FpImageDevice *img_dev) { - fpi_image_device_deactivate_complete(img_dev, NULL); + FpDevice* dev = FP_DEVICE(img_dev); + goodix_reset_state(dev); + GError* error = NULL; + goodix_shutdown_tls(dev, &error); + fpi_image_device_deactivate_complete(img_dev, error); } // ---- DEV SECTION END ---- diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index 473fc4b6b..c09979ce3 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -124,9 +124,7 @@ static void tls_config_ssl(SSL* ssl) static void* goodix_tls_init_serve(void* me) { GoodixTlsServer* self = me; - self->ssl_layer = SSL_new(self->ssl_ctx); - tls_config_ssl(self->ssl_layer); - SSL_set_fd(self->ssl_layer, self->sock_fd); + fp_dbg("TLS server waiting to accept..."); int retr = SSL_accept(self->ssl_layer); fp_dbg("TLS server accept done"); @@ -178,6 +176,10 @@ gboolean goodix_tls_server_init(GoodixTlsServer* self, GError** error) "context"); return FALSE; } + self->ssl_layer = SSL_new(self->ssl_ctx); + tls_config_ssl(self->ssl_layer); + SSL_set_fd(self->ssl_layer, self->sock_fd); + pthread_create(&self->serve_thread, 0, goodix_tls_init_serve, self); return TRUE; From 130502b8f6eaf189e2a610fa0ba024c7671543cd Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Mon, 6 Sep 2021 16:17:45 +0100 Subject: [PATCH 27/57] fix: segfault on ssl read error --- libfprint/drivers/goodixtls/goodix.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 85c992005..85496e184 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -1283,10 +1283,11 @@ static void goodix_tls_ready_image_handler(FpDevice* dev, guint8* data, GError* error) { - g_autofree GoodixCallbackInfo* cb_info = user_data; + GoodixCallbackInfo* cb_info = user_data; GoodixImageCallback callback = (GoodixImageCallback) cb_info->callback; if (error) { - callback(dev, NULL, 0, error, cb_info->user_data); + callback(dev, NULL, 0, cb_info->user_data, error); + g_free(cb_info); return; } FpiDeviceGoodixTls* self = FPI_DEVICE_GOODIXTLS(dev); @@ -1299,11 +1300,13 @@ static void goodix_tls_ready_image_handler(FpDevice* dev, guint8* data, GError* err = NULL; int read_size = goodix_tls_server_receive(priv->tls_hop, buff, size, &err); if (read_size <= 0) { - callback(dev, NULL, 0, err, cb_info->user_data); + callback(dev, NULL, 0, cb_info->user_data, err); + g_free(cb_info); return; } callback(dev, buff, read_size, cb_info->user_data, NULL); + g_free(cb_info); } void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, From c15bce33d505fb6edd78db9c5d6c39b0a9075a49 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Mon, 6 Sep 2021 16:53:11 +0100 Subject: [PATCH 28/57] chore: working on noise reduction --- libfprint/drivers/goodixtls/goodix511.c | 90 ++++++++++++++++++++++--- libfprint/drivers/goodixtls/goodixtls.c | 3 +- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 50557df15..fceb3c290 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -54,6 +54,8 @@ struct _FpiDeviceGoodixTls511 { guint8* otp; GSList* frames; + + guint8 empty_img[GOODIX511_FRAME_SIZE]; }; G_DECLARE_FINAL_TYPE(FpiDeviceGoodixTls511, fpi_device_goodixtls511, FPI, @@ -357,6 +359,7 @@ static void activate_complete(FpiSsm* ssm, FpDevice* dev, GError* error) // ---- SCAN SECTION START ---- enum SCAN_STAGES { + SCAN_STAGE_CALIBRATE, SCAN_STAGE_SWITCH_TO_FDT_MODE, SCAN_STAGE_SWITCH_TO_FDT_DOWN, SCAN_STAGE_GET_IMG, @@ -384,20 +387,50 @@ static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, // Bitdepth is 12, but we have to fit it in a byte static unsigned char squash(int v) { return v / 16; } -static void decode_frame(guint8* raw_frame, GSList** frames) +static void decode_frame(guint8 frame[GOODIX511_FRAME_SIZE], + const guint8* raw_frame) { - const int frame_size = GOODIX511_FRAME_SIZE * 2; - struct fpi_frame* frame = g_malloc(frame_size + sizeof(struct fpi_frame)); - guint8* pix = frame->data; + guint8* pix = frame; for (int i = 8; i != GOODIX511_RAW_FRAME_SIZE - 5; i += 6) { - guint8* chunk = raw_frame + i; + const guint8* chunk = raw_frame + i; *pix++ = squash(((chunk[0] & 0xf) << 8) + chunk[1]); *pix++ = squash((chunk[3] << 4) + (chunk[0] >> 4)); *pix++ = squash(((chunk[5] & 0xf) << 8) + chunk[2]); *pix++ = squash((chunk[4] << 4) + (chunk[5] >> 4)); } - *frames = g_slist_append(*frames, frame); +} + +static void postprocess_frame(guint8 frame[GOODIX511_FRAME_SIZE], + guint8 background[GOODIX511_FRAME_SIZE]) +{ + + for (int i = 0; i != GOODIX511_FRAME_SIZE; ++i) { + guint8* og_px = frame + i; + guint8 bg_px = background[i]; + if (bg_px > *og_px) { + *og_px = 0; + } + else { + *og_px -= bg_px; + } + //*og_px -= (255 - bg_px); + } +} +typedef struct _frame_processing_info { + FpiDeviceGoodixTls511* dev; + GSList** frames; + +} frame_processing_info; + +static void process_frame(guint8* raw_frame, frame_processing_info* info) +{ + struct fpi_frame* frame = + g_malloc(GOODIX511_FRAME_SIZE + sizeof(struct fpi_frame)); + decode_frame(frame->data, raw_frame); + postprocess_frame(frame->data, info->dev->empty_img); + + *(info->frames) = g_slist_append(*(info->frames), frame); } static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, @@ -425,8 +458,9 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, assembly_ctx.get_pixel = get_pix; GSList* frames = NULL; + frame_processing_info pinfo = {.dev = self, .frames = &frames}; - g_slist_foreach(raw_frames, (GFunc) decode_frame, &frames); + g_slist_foreach(raw_frames, (GFunc) process_frame, &pinfo); fpi_do_movement_estimation(&assembly_ctx, frames); FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); @@ -441,9 +475,45 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, } } +enum scan_empty_img_state { + SCAN_EMPTY_NAV0, + SCAN_EMPTY_GET_IMG, + + SCAN_EMPTY_NUM, +}; + +static void on_scan_empty_img(FpDevice* dev, guint8* data, guint16 length, + gpointer ssm, GError* error) +{ + if (error) { + fpi_ssm_mark_failed(ssm, error); + return; + } + FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); + decode_frame(self->empty_img, data); + fpi_ssm_next_state(ssm); +} +static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) +{ + + switch (fpi_ssm_get_cur_state(ssm)) { + case SCAN_EMPTY_NAV0: + goodix_send_nav_0(dev, check_none_cmd, ssm); + break; + + case SCAN_EMPTY_GET_IMG: + goodix_tls_read_image(dev, on_scan_empty_img, ssm); + break; + } +} + +static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) +{ + fpi_ssm_start_subsm(ssm, fpi_ssm_new(dev, scan_empty_run, SCAN_EMPTY_NUM)); +} + static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { - g_object_ref(fpi_ssm_get_device(ssm)); goodix_tls_read_image(dev, scan_on_read_img, ssm); } @@ -462,6 +532,10 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); switch (fpi_ssm_get_cur_state(ssm)) { + case SCAN_STAGE_CALIBRATE: + scan_empty_img(dev, ssm); + break; + case SCAN_STAGE_SWITCH_TO_FDT_MODE: goodix_send_mcu_switch_to_fdt_mode(dev, (guint8*) fdt_switch_state_mode, sizeof(fdt_switch_state_mode), NULL, diff --git a/libfprint/drivers/goodixtls/goodixtls.c b/libfprint/drivers/goodixtls/goodixtls.c index c09979ce3..c348b97e6 100644 --- a/libfprint/drivers/goodixtls/goodixtls.c +++ b/libfprint/drivers/goodixtls/goodixtls.c @@ -107,8 +107,7 @@ int goodix_tls_server_receive(GoodixTlsServer* self, guint8* data, { int retr = SSL_read(self->ssl_layer, data, length * sizeof(guint8)); if (retr <= 0) { - g_set_error(error, g_io_channel_error_quark(), retr, - ""); // err_from_ssl(retr); + *error = err_from_ssl(); } return retr; } From bf3337f941f9ededa63b60a4586fd64a47576f4a Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Mon, 6 Sep 2021 17:03:08 +0100 Subject: [PATCH 29/57] chore: working on noise reduction --- libfprint/drivers/goodixtls/goodix511.c | 61 ++++++++++++++++++------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index fceb3c290..058904e46 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -48,6 +48,8 @@ #define GOODIX511_RAW_FRAME_SIZE 8 + GOODIX511_FRAME_SIZE / 4 * 6 + 5 #define GOODIX511_CAP_FRAMES 3 // Number of frames we capture per swipe +typedef unsigned short Goodix511Pix; + struct _FpiDeviceGoodixTls511 { FpiDeviceGoodixTls parent; @@ -55,7 +57,7 @@ struct _FpiDeviceGoodixTls511 { GSList* frames; - guint8 empty_img[GOODIX511_FRAME_SIZE]; + Goodix511Pix empty_img[GOODIX511_FRAME_SIZE]; }; G_DECLARE_FINAL_TYPE(FpiDeviceGoodixTls511, fpi_device_goodixtls511, FPI, @@ -387,34 +389,53 @@ static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, // Bitdepth is 12, but we have to fit it in a byte static unsigned char squash(int v) { return v / 16; } -static void decode_frame(guint8 frame[GOODIX511_FRAME_SIZE], +static void decode_frame(Goodix511Pix frame[GOODIX511_FRAME_SIZE], const guint8* raw_frame) { - guint8* pix = frame; + Goodix511Pix* pix = frame; for (int i = 8; i != GOODIX511_RAW_FRAME_SIZE - 5; i += 6) { const guint8* chunk = raw_frame + i; - *pix++ = squash(((chunk[0] & 0xf) << 8) + chunk[1]); - *pix++ = squash((chunk[3] << 4) + (chunk[0] >> 4)); - *pix++ = squash(((chunk[5] & 0xf) << 8) + chunk[2]); - *pix++ = squash((chunk[4] << 4) + (chunk[5] >> 4)); + *pix++ = ((chunk[0] & 0xf) << 8) + chunk[1]; + *pix++ = (chunk[3] << 4) + (chunk[0] >> 4); + *pix++ = ((chunk[5] & 0xf) << 8) + chunk[2]; + *pix++ = (chunk[4] << 4) + (chunk[5] >> 4); } } -static void postprocess_frame(guint8 frame[GOODIX511_FRAME_SIZE], - guint8 background[GOODIX511_FRAME_SIZE]) +/** + * @brief Squashes the 12 bit pixels of a raw frame into the 4 bit pixels used + * by libfprint + * + * @param frame + * @param squashed + */ +static void squash_frame(Goodix511Pix* frame, guint8* squashed) +{ + for (int i = 0; i != GOODIX511_FRAME_SIZE; ++i) { + squashed[i] = squash(frame[i]); + } +} + +/** + * @brief Subtracts the background from the frame + * + * @param frame + * @param background + */ +static void postprocess_frame(Goodix511Pix frame[GOODIX511_FRAME_SIZE], + Goodix511Pix background[GOODIX511_FRAME_SIZE]) { for (int i = 0; i != GOODIX511_FRAME_SIZE; ++i) { - guint8* og_px = frame + i; - guint8 bg_px = background[i]; + Goodix511Pix* og_px = frame + i; + Goodix511Pix bg_px = background[i]; if (bg_px > *og_px) { *og_px = 0; } else { *og_px -= bg_px; } - //*og_px -= (255 - bg_px); } } typedef struct _frame_processing_info { @@ -423,16 +444,23 @@ typedef struct _frame_processing_info { } frame_processing_info; -static void process_frame(guint8* raw_frame, frame_processing_info* info) +static void process_frame(Goodix511Pix* raw_frame, frame_processing_info* info) { struct fpi_frame* frame = g_malloc(GOODIX511_FRAME_SIZE + sizeof(struct fpi_frame)); - decode_frame(frame->data, raw_frame); - postprocess_frame(frame->data, info->dev->empty_img); + postprocess_frame(raw_frame, info->dev->empty_img); + squash_frame(raw_frame, frame->data); *(info->frames) = g_slist_append(*(info->frames), frame); } +static void save_frame(FpiDeviceGoodixTls511* self, guint8* raw) +{ + Goodix511Pix* frame = malloc(GOODIX511_FRAME_SIZE * sizeof(Goodix511Pix)); + decode_frame(frame, raw); + self->frames = g_slist_append(self->frames, frame); +} + static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, gpointer ssm, GError* err) { @@ -442,12 +470,11 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, } FpiDeviceGoodixTls511* self = FPI_DEVICE_GOODIXTLS511(dev); + save_frame(self, data); if (g_slist_length(self->frames) <= GOODIX511_CAP_FRAMES) { - self->frames = g_slist_append(self->frames, data); fpi_ssm_jump_to_state(ssm, SCAN_STAGE_SWITCH_TO_FDT_MODE); } else { - self->frames = g_slist_append(self->frames, data); GSList* raw_frames = g_slist_nth(self->frames, 1); FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); From 23e97d2ed86e144474c88fd1d798cd06dc54ce5c Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Tue, 7 Sep 2021 14:54:03 +0100 Subject: [PATCH 30/57] chore: copied pixel squash algorithm from elan --- libfprint/drivers/goodixtls/goodix511.c | 85 ++++++++++++++++++++----- 1 file changed, 69 insertions(+), 16 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 058904e46..62b552ea3 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -28,6 +28,7 @@ #include "glibconfig.h" #include "gusb/gusb-device.h" #include +#include #define FP_COMPONENT "goodixtls511" #include @@ -40,13 +41,15 @@ #include -#define GOODIX511_WIDTH 88 +#define GOODIX511_WIDTH 64 #define GOODIX511_HEIGHT 80 -#define GOODIX511_FRAME_SIZE 80 * 88 +#define GOODIX511_SCAN_WIDTH 88 +#define GOODIX511_FRAME_SIZE (GOODIX511_WIDTH * GOODIX511_HEIGHT) // For every 4 pixels there are 6 bytes and there are 8 extra start bytes and 5 // extra end -#define GOODIX511_RAW_FRAME_SIZE 8 + GOODIX511_FRAME_SIZE / 4 * 6 + 5 -#define GOODIX511_CAP_FRAMES 3 // Number of frames we capture per swipe +#define GOODIX511_RAW_FRAME_SIZE \ + 8 + (GOODIX511_HEIGHT * GOODIX511_SCAN_WIDTH) / 4 * 6 + 5 +#define GOODIX511_CAP_FRAMES 5 // Number of frames we capture per swipe typedef unsigned short Goodix511Pix; @@ -383,7 +386,7 @@ static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, struct fpi_frame* frame, unsigned int x, unsigned int y) { - return frame->data[x + y * ctx->frame_width]; + return frame->data[x + y * GOODIX511_WIDTH]; } // Bitdepth is 12, but we have to fit it in a byte @@ -393,7 +396,8 @@ static void decode_frame(Goodix511Pix frame[GOODIX511_FRAME_SIZE], const guint8* raw_frame) { - Goodix511Pix* pix = frame; + Goodix511Pix uncropped[GOODIX511_SCAN_WIDTH * GOODIX511_HEIGHT]; + Goodix511Pix* pix = uncropped; for (int i = 8; i != GOODIX511_RAW_FRAME_SIZE - 5; i += 6) { const guint8* chunk = raw_frame + i; *pix++ = ((chunk[0] & 0xf) << 8) + chunk[1]; @@ -401,19 +405,50 @@ static void decode_frame(Goodix511Pix frame[GOODIX511_FRAME_SIZE], *pix++ = ((chunk[5] & 0xf) << 8) + chunk[2]; *pix++ = (chunk[4] << 4) + (chunk[5] >> 4); } + for (int y = 0; y != GOODIX511_HEIGHT; ++y) { + for (int x = 0; x != GOODIX511_WIDTH; ++x) { + const int idx = x + y * GOODIX511_SCAN_WIDTH; + frame[x + y * GOODIX511_WIDTH] = uncropped[idx]; + } + } +} +static int goodix_cmp_short(const void* a, const void* b) +{ + return (int) (*(short*) a - *(short*) b); } /** * @brief Squashes the 12 bit pixels of a raw frame into the 4 bit pixels used - * by libfprint + * by libfprint. + * @details Borrowed from the elan driver. We reduce frames to + * within the max and min. * * @param frame * @param squashed */ -static void squash_frame(Goodix511Pix* frame, guint8* squashed) +static void squash_frame_linear(Goodix511Pix* frame, guint8* squashed) { + Goodix511Pix min = 0xffff; + Goodix511Pix max = 0; + + for (int i = 0; i != GOODIX511_FRAME_SIZE; ++i) { + const Goodix511Pix pix = frame[i]; + if (pix < min) { + min = pix; + } + if (pix > max) { + max = pix; + } + } + for (int i = 0; i != GOODIX511_FRAME_SIZE; ++i) { - squashed[i] = squash(frame[i]); + const Goodix511Pix pix = frame[i]; + if (pix - min == 0 || max - min == 0) { + squashed[i] = 0; + } + else { + squashed[i] = (pix - min) * 0xff / (max - min); + } } } @@ -423,21 +458,28 @@ static void squash_frame(Goodix511Pix* frame, guint8* squashed) * @param frame * @param background */ -static void postprocess_frame(Goodix511Pix frame[GOODIX511_FRAME_SIZE], - Goodix511Pix background[GOODIX511_FRAME_SIZE]) +static gboolean postprocess_frame(Goodix511Pix frame[GOODIX511_FRAME_SIZE], + Goodix511Pix background[GOODIX511_FRAME_SIZE]) { - + int sum = 0; for (int i = 0; i != GOODIX511_FRAME_SIZE; ++i) { Goodix511Pix* og_px = frame + i; - Goodix511Pix bg_px = background[i]; + Goodix511Pix bg_px = background[i] / 2; if (bg_px > *og_px) { *og_px = 0; } else { *og_px -= bg_px; } + sum += *og_px; + } + if (sum == 0) { + fp_warn("frame darker than background, finger on scanner during " + "calibration?"); } + return sum != 0; } + typedef struct _frame_processing_info { FpiDeviceGoodixTls511* dev; GSList** frames; @@ -449,7 +491,7 @@ static void process_frame(Goodix511Pix* raw_frame, frame_processing_info* info) struct fpi_frame* frame = g_malloc(GOODIX511_FRAME_SIZE + sizeof(struct fpi_frame)); postprocess_frame(raw_frame, info->dev->empty_img); - squash_frame(raw_frame, frame->data); + squash_frame_linear(raw_frame, frame->data); *(info->frames) = g_slist_append(*(info->frames), frame); } @@ -481,7 +523,7 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, struct fpi_frame_asmbl_ctx assembly_ctx; assembly_ctx.frame_width = GOODIX511_WIDTH; assembly_ctx.frame_height = GOODIX511_HEIGHT; - assembly_ctx.image_width = GOODIX511_WIDTH; + assembly_ctx.image_width = GOODIX511_WIDTH * 3 / 2; assembly_ctx.get_pixel = get_pix; GSList* frames = NULL; @@ -494,6 +536,8 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, img->flags |= FPI_IMAGE_PARTIAL; g_slist_free_full(frames, g_free); + g_slist_free_full(self->frames, g_free); + self->frames = g_slist_alloc(); fpi_image_device_image_captured(img_dev, img); fpi_image_device_report_finger_status(img_dev, FALSE); @@ -643,11 +687,20 @@ static void dev_change_state(FpImageDevice* img_dev, FpiImageDeviceState state) } } +static void goodix511_reset_state(FpiDeviceGoodixTls511* self) +{ + /*if (self->otp) { + free(self->otp); + self->otp = NULL; + }*/ +} + static void dev_deactivate(FpImageDevice *img_dev) { FpDevice* dev = FP_DEVICE(img_dev); goodix_reset_state(dev); GError* error = NULL; goodix_shutdown_tls(dev, &error); + goodix511_reset_state(FPI_DEVICE_GOODIXTLS511(img_dev)); fpi_image_device_deactivate_complete(img_dev, error); } @@ -673,7 +726,7 @@ static void fpi_device_goodixtls511_class_init( dev_class->type = FP_DEVICE_TYPE_USB; dev_class->id_table = id_table; - dev_class->scan_type = FP_SCAN_TYPE_SWIPE; + dev_class->scan_type = FP_SCAN_TYPE_PRESS; // TODO img_dev_class->bz3_threshold = 24; From 692d6738d79f67c8813d8d9e5d5b43e365d54d57 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Tue, 7 Sep 2021 16:41:22 +0100 Subject: [PATCH 31/57] chore: remove less minutiae --- libfprint/drivers/goodixtls/goodix511.c | 2 +- libfprint/fp-image.c | 15 +++++++++++++++ libfprint/fpi-image.h | 9 +++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 62b552ea3..c3b8f5aea 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -533,7 +533,7 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, fpi_do_movement_estimation(&assembly_ctx, frames); FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); - img->flags |= FPI_IMAGE_PARTIAL; + img->flags |= FPI_IMAGE_PARTIAL | FPI_IMAGE_REMOVE_LESS_MINUTIAE; g_slist_free_full(frames, g_free); g_slist_free_full(self->frames, g_free); diff --git a/libfprint/fp-image.c b/libfprint/fp-image.c index 51732c1bf..3cef27d94 100644 --- a/libfprint/fp-image.c +++ b/libfprint/fp-image.c @@ -298,6 +298,21 @@ fp_image_detect_minutiae_thread_func (GTask *task, lfsparms = g_memdup (&g_lfsparms_V2, sizeof (LFSPARMS)); lfsparms->remove_perimeter_pts = data->flags & FPI_IMAGE_PARTIAL ? TRUE : FALSE; + if (data->flags & FPI_IMAGE_REMOVE_LESS_MINUTIAE) + { + // Effectively disabling several steps of the remove false minutiae step by making the remove condition unarchivable + lfsparms->max_rmtest_dist = 0; + lfsparms->max_hook_len = 0; + lfsparms->max_half_loop = 0; + lfsparms->small_loop_len = 0; + lfsparms->max_overlap_dist = 0; + lfsparms->max_overlap_join_dist = 0; + lfsparms->min_malformation_ratio = INT_MAX; + lfsparms->max_malformation_dist = INT_MAX; + lfsparms->pores_max_ratio = 0; + } + + timer = g_timer_new (); r = get_minutiae (&minutiae, &quality_map, &direction_map, &low_contrast_map, &low_flow_map, &high_curve_map, diff --git a/libfprint/fpi-image.h b/libfprint/fpi-image.h index fcd62b8e0..80cc170bf 100644 --- a/libfprint/fpi-image.h +++ b/libfprint/fpi-image.h @@ -34,10 +34,11 @@ * rely on the image to be normalized by libfprint before further processing. */ typedef enum { - FPI_IMAGE_V_FLIPPED = 1 << 0, - FPI_IMAGE_H_FLIPPED = 1 << 1, - FPI_IMAGE_COLORS_INVERTED = 1 << 2, - FPI_IMAGE_PARTIAL = 1 << 3, + FPI_IMAGE_V_FLIPPED = 1 << 0, + FPI_IMAGE_H_FLIPPED = 1 << 1, + FPI_IMAGE_COLORS_INVERTED = 1 << 2, + FPI_IMAGE_PARTIAL = 1 << 3, + FPI_IMAGE_REMOVE_LESS_MINUTIAE = 1 << 4, } FpiImageFlags; /** From e9c41b9893a6d632abec6058bbf75039ab662a27 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Tue, 7 Sep 2021 17:41:13 +0100 Subject: [PATCH 32/57] feat: sort of working verification --- libfprint/drivers/goodixtls/goodix511.c | 48 +++++++++++++++++-------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index c3b8f5aea..5c4483dfe 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -49,7 +49,7 @@ // extra end #define GOODIX511_RAW_FRAME_SIZE \ 8 + (GOODIX511_HEIGHT * GOODIX511_SCAN_WIDTH) / 4 * 6 + 5 -#define GOODIX511_CAP_FRAMES 5 // Number of frames we capture per swipe +#define GOODIX511_CAP_FRAMES 20 // Number of frames we capture per swipe typedef unsigned short Goodix511Pix; @@ -417,6 +417,23 @@ static int goodix_cmp_short(const void* a, const void* b) return (int) (*(short*) a - *(short*) b); } +static void rotate_frame(Goodix511Pix frame[GOODIX511_FRAME_SIZE]) +{ + Goodix511Pix buff[GOODIX511_FRAME_SIZE]; + + for (int y = 0; y != GOODIX511_HEIGHT; ++y) { + for (int x = 0; x != GOODIX511_WIDTH; ++x) { + buff[x * GOODIX511_WIDTH + y] = frame[x + y * GOODIX511_WIDTH]; + } + } + memcpy(frame, buff, GOODIX511_FRAME_SIZE); +} +static void squash_frame(Goodix511Pix* frame, guint8* squashed) +{ + for (int i = 0; i != GOODIX511_FRAME_SIZE; ++i) { + squashed[i] = squash(frame[i]); + } +} /** * @brief Squashes the 12 bit pixels of a raw frame into the 4 bit pixels used * by libfprint. @@ -464,14 +481,16 @@ static gboolean postprocess_frame(Goodix511Pix frame[GOODIX511_FRAME_SIZE], int sum = 0; for (int i = 0; i != GOODIX511_FRAME_SIZE; ++i) { Goodix511Pix* og_px = frame + i; - Goodix511Pix bg_px = background[i] / 2; - if (bg_px > *og_px) { - *og_px = 0; - } - else { - *og_px -= bg_px; - } - sum += *og_px; + Goodix511Pix bg_px = // background[i]; + /*if (bg_px > *og_px) { + *og_px = 0; + } + else { + *og_px -= bg_px; + }*/ + //*og_px = MAX(bg_px - *og_px, 0); + //* og_px = MAX(*og_px - bg_px, 0); + sum += *og_px; } if (sum == 0) { fp_warn("frame darker than background, finger on scanner during " @@ -491,7 +510,7 @@ static void process_frame(Goodix511Pix* raw_frame, frame_processing_info* info) struct fpi_frame* frame = g_malloc(GOODIX511_FRAME_SIZE + sizeof(struct fpi_frame)); postprocess_frame(raw_frame, info->dev->empty_img); - squash_frame_linear(raw_frame, frame->data); + squash_frame(raw_frame, frame->data); *(info->frames) = g_slist_append(*(info->frames), frame); } @@ -523,21 +542,22 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, struct fpi_frame_asmbl_ctx assembly_ctx; assembly_ctx.frame_width = GOODIX511_WIDTH; assembly_ctx.frame_height = GOODIX511_HEIGHT; - assembly_ctx.image_width = GOODIX511_WIDTH * 3 / 2; + assembly_ctx.image_width = GOODIX511_WIDTH * 2; assembly_ctx.get_pixel = get_pix; GSList* frames = NULL; frame_processing_info pinfo = {.dev = self, .frames = &frames}; g_slist_foreach(raw_frames, (GFunc) process_frame, &pinfo); + // frames = g_slist_reverse(frames); fpi_do_movement_estimation(&assembly_ctx, frames); FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); - img->flags |= FPI_IMAGE_PARTIAL | FPI_IMAGE_REMOVE_LESS_MINUTIAE; + img->flags |= FPI_IMAGE_PARTIAL; g_slist_free_full(frames, g_free); - g_slist_free_full(self->frames, g_free); - self->frames = g_slist_alloc(); + // g_slist_free_full(self->frames, g_free); + // self->frames = g_slist_alloc(); fpi_image_device_image_captured(img_dev, img); fpi_image_device_report_finger_status(img_dev, FALSE); From fae3acda73a15c25d2e426f60bc4cc3e08b83cb8 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Tue, 7 Sep 2021 17:41:34 +0100 Subject: [PATCH 33/57] chore: revert "chore: remove less minutiae" This reverts commit 692d6738d79f67c8813d8d9e5d5b43e365d54d57. --- libfprint/fp-image.c | 15 --------------- libfprint/fpi-image.h | 9 ++++----- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/libfprint/fp-image.c b/libfprint/fp-image.c index 3cef27d94..51732c1bf 100644 --- a/libfprint/fp-image.c +++ b/libfprint/fp-image.c @@ -298,21 +298,6 @@ fp_image_detect_minutiae_thread_func (GTask *task, lfsparms = g_memdup (&g_lfsparms_V2, sizeof (LFSPARMS)); lfsparms->remove_perimeter_pts = data->flags & FPI_IMAGE_PARTIAL ? TRUE : FALSE; - if (data->flags & FPI_IMAGE_REMOVE_LESS_MINUTIAE) - { - // Effectively disabling several steps of the remove false minutiae step by making the remove condition unarchivable - lfsparms->max_rmtest_dist = 0; - lfsparms->max_hook_len = 0; - lfsparms->max_half_loop = 0; - lfsparms->small_loop_len = 0; - lfsparms->max_overlap_dist = 0; - lfsparms->max_overlap_join_dist = 0; - lfsparms->min_malformation_ratio = INT_MAX; - lfsparms->max_malformation_dist = INT_MAX; - lfsparms->pores_max_ratio = 0; - } - - timer = g_timer_new (); r = get_minutiae (&minutiae, &quality_map, &direction_map, &low_contrast_map, &low_flow_map, &high_curve_map, diff --git a/libfprint/fpi-image.h b/libfprint/fpi-image.h index 80cc170bf..fcd62b8e0 100644 --- a/libfprint/fpi-image.h +++ b/libfprint/fpi-image.h @@ -34,11 +34,10 @@ * rely on the image to be normalized by libfprint before further processing. */ typedef enum { - FPI_IMAGE_V_FLIPPED = 1 << 0, - FPI_IMAGE_H_FLIPPED = 1 << 1, - FPI_IMAGE_COLORS_INVERTED = 1 << 2, - FPI_IMAGE_PARTIAL = 1 << 3, - FPI_IMAGE_REMOVE_LESS_MINUTIAE = 1 << 4, + FPI_IMAGE_V_FLIPPED = 1 << 0, + FPI_IMAGE_H_FLIPPED = 1 << 1, + FPI_IMAGE_COLORS_INVERTED = 1 << 2, + FPI_IMAGE_PARTIAL = 1 << 3, } FpiImageFlags; /** From 2be196f32514ba03daa8b093bda93ecc7fe11707 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Tue, 7 Sep 2021 17:45:02 +0100 Subject: [PATCH 34/57] chore: increase captured frames to 40 --- libfprint/drivers/goodixtls/goodix511.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 5c4483dfe..092ecacf1 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -49,7 +49,7 @@ // extra end #define GOODIX511_RAW_FRAME_SIZE \ 8 + (GOODIX511_HEIGHT * GOODIX511_SCAN_WIDTH) / 4 * 6 + 5 -#define GOODIX511_CAP_FRAMES 20 // Number of frames we capture per swipe +#define GOODIX511_CAP_FRAMES 40 // Number of frames we capture per swipe typedef unsigned short Goodix511Pix; @@ -707,13 +707,7 @@ static void dev_change_state(FpImageDevice* img_dev, FpiImageDeviceState state) } } -static void goodix511_reset_state(FpiDeviceGoodixTls511* self) -{ - /*if (self->otp) { - free(self->otp); - self->otp = NULL; - }*/ -} +static void goodix511_reset_state(FpiDeviceGoodixTls511* self) {} static void dev_deactivate(FpImageDevice *img_dev) { FpDevice* dev = FP_DEVICE(img_dev); From 14a877a5a56d47aad9400a71a1c39c3df45ffc63 Mon Sep 17 00:00:00 2001 From: Ash England-Elbro Date: Tue, 7 Sep 2021 17:47:36 +0100 Subject: [PATCH 35/57] chore: remove uneeded calibration step --- libfprint/drivers/goodixtls/goodix511.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 092ecacf1..f84f99141 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -364,7 +364,6 @@ static void activate_complete(FpiSsm* ssm, FpDevice* dev, GError* error) // ---- SCAN SECTION START ---- enum SCAN_STAGES { - SCAN_STAGE_CALIBRATE, SCAN_STAGE_SWITCH_TO_FDT_MODE, SCAN_STAGE_SWITCH_TO_FDT_DOWN, SCAN_STAGE_GET_IMG, @@ -623,9 +622,6 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); switch (fpi_ssm_get_cur_state(ssm)) { - case SCAN_STAGE_CALIBRATE: - scan_empty_img(dev, ssm); - break; case SCAN_STAGE_SWITCH_TO_FDT_MODE: goodix_send_mcu_switch_to_fdt_mode(dev, (guint8*) fdt_switch_state_mode, From 93ce734e03acd9bc8f3e4389a6b55339ed3e4af7 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 19:06:34 +0200 Subject: [PATCH 36/57] Remove 521d from the unsupported devices list --- data/autosuspend.hwdb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb index d8d30b6e5..74b1b82d4 100644 --- a/data/autosuspend.hwdb +++ b/data/autosuspend.hwdb @@ -168,6 +168,10 @@ usb:v27C6p6A94* ID_AUTOSUSPEND=1 ID_PERSIST=0 +# Supported by libfprint driver goodixtls52xd +usb:v27C6p521D* + ID_AUTOSUSPEND=1 + # Supported by libfprint driver goodixtls511 usb:v27c6p5110* ID_AUTOSUSPEND=1 @@ -309,7 +313,6 @@ usb:v1C7Ap0575* usb:v27C6p5042* usb:v27C6p5117* usb:v27C6p5201* -usb:v27C6p521D* usb:v27C6p5301* usb:v27C6p530C* usb:v27C6p532D* From becc6f233dd41215b029a1b857a03c5fa19c780b Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 19:08:18 +0200 Subject: [PATCH 37/57] Add TLS_DATA flag to proto definitions --- libfprint/drivers/goodixtls/goodix_proto.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libfprint/drivers/goodixtls/goodix_proto.h b/libfprint/drivers/goodixtls/goodix_proto.h index d42ca870e..af2316d29 100644 --- a/libfprint/drivers/goodixtls/goodix_proto.h +++ b/libfprint/drivers/goodixtls/goodix_proto.h @@ -26,6 +26,7 @@ #define GOODIX_FLAGS_MSG_PROTOCOL (0xa0) #define GOODIX_FLAGS_TLS (0xb0) +#define GOODIX_FLAGS_TLS_DATA (0xb2) #define GOODIX_CMD_NOP (0x00) #define GOODIX_CMD_MCU_GET_IMAGE (0x20) From 8410de123ac97a37ff834571550f874d0de2d871 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 19:17:57 +0200 Subject: [PATCH 38/57] Adjust preset_psk to python protocol --- libfprint/drivers/goodixtls/goodix_proto.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/goodixtls/goodix_proto.h b/libfprint/drivers/goodixtls/goodix_proto.h index af2316d29..493419a1c 100644 --- a/libfprint/drivers/goodixtls/goodix_proto.h +++ b/libfprint/drivers/goodixtls/goodix_proto.h @@ -110,8 +110,9 @@ typedef struct __attribute__((__packed__)) _GoodixQueryMcuState { } GoodixQueryMcuState; typedef struct __attribute__((__packed__)) _GoodixPresetPsk { - guint32 flags; guint32 length; + guint32 offset; + guint32 flags; } GoodixPresetPsk; typedef struct __attribute__((__packed__)) _GoodixDefault { From ee8c43ce629709d09cc97572689bd0ca09b5cfec Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 21:13:48 +0200 Subject: [PATCH 39/57] Add support for TLS_DATA handling --- libfprint/drivers/goodixtls/goodix.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 85496e184..0093a0465 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -350,6 +350,12 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { // TODO break; + case GOODIX_FLAGS_TLS_DATA:° + fp_dbg("Got TLS data msg"); + // GOODIX 52xd: Remove first 9 to get valid TLS content + goodix_receive_done(dev, payload+9, payload_len-9, NULL); + break; + default: fp_warn("Unknown flags: 0x%02x", flags); break; From 65f811da558871a8c55fc53e56b576f6e8b8ba49 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 21:42:16 +0200 Subject: [PATCH 40/57] Migrate mcu_get_image payload out of goodix core --- libfprint/drivers/goodixtls/goodix.c | 9 ++++----- libfprint/drivers/goodixtls/goodix.h | 4 ++-- libfprint/drivers/goodixtls/goodix511.c | 6 ++++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 0093a0465..a734553b3 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -350,7 +350,7 @@ void goodix_receive_pack(FpDevice *dev, guint8 *data, guint32 length) { // TODO break; - case GOODIX_FLAGS_TLS_DATA:° + case GOODIX_FLAGS_TLS_DATA: fp_dbg("Got TLS data msg"); // GOODIX 52xd: Remove first 9 to get valid TLS content goodix_receive_done(dev, payload+9, payload_len-9, NULL); @@ -551,10 +551,9 @@ void goodix_send_nop(FpDevice *dev, GoodixNoneCallback callback, goodix_receive_done(dev, NULL, 0, NULL); } -void goodix_send_mcu_get_image(FpDevice* dev, GoodixImageCallback callback, +void goodix_send_mcu_get_image(FpDevice* dev, guint8* payload, GoodixImageCallback callback, gpointer user_data) { - GoodixDefault payload = {.unused_flags = 0x01}; GoodixCallbackInfo* cb_info; if (callback) { @@ -1315,7 +1314,7 @@ static void goodix_tls_ready_image_handler(FpDevice* dev, guint8* data, g_free(cb_info); } -void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, +void goodix_tls_read_image(FpDevice* dev, guint8* payload, GoodixImageCallback callback, gpointer user_data) { g_assert(callback); @@ -1324,7 +1323,7 @@ void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, cb_info->callback = G_CALLBACK(callback); cb_info->user_data = user_data; - goodix_send_mcu_get_image(dev, goodix_tls_ready_image_handler, cb_info); + goodix_send_mcu_get_image(dev, payload, goodix_tls_ready_image_handler, cb_info); } // ---- TLS SECTION END ---- diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index f4f8456ad..90a844ff7 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -137,7 +137,7 @@ void goodix_send_protocol(FpDevice *dev, guint8 cmd, guint8 *payload, void goodix_send_nop(FpDevice *dev, GoodixNoneCallback callback, gpointer user_data); -void goodix_send_mcu_get_image(FpDevice *dev, GoodixImageCallback callback, +void goodix_send_mcu_get_image(FpDevice *dev, guint8* payload, GoodixImageCallback callback, gpointer user_data); void goodix_send_mcu_switch_to_fdt_down(FpDevice *dev, guint8 *mode, @@ -246,7 +246,7 @@ void goodix_tls(FpDevice* dev, GoodixNoneCallback callback, gpointer user_data); gboolean goodix_shutdown_tls(FpDevice* dev, GError** error); -void goodix_tls_read_image(FpDevice* dev, GoodixImageCallback callback, +void goodix_tls_read_image(FpDevice* dev, guint8* payload, GoodixImageCallback callback, gpointer user_data); void goodix_tls_decrypt_image(FpDevice* dev, guint8** data, guint16* len); diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index f84f99141..a7b073b9a 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -592,7 +592,8 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) break; case SCAN_EMPTY_GET_IMG: - goodix_tls_read_image(dev, on_scan_empty_img, ssm); + GoodixDefault payload = {.unused_flags = 0x01}; + goodix_tls_read_image(dev, &payload, on_scan_empty_img, ssm); break; } } @@ -604,7 +605,8 @@ static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { - goodix_tls_read_image(dev, scan_on_read_img, ssm); + GoodixDefault payload = {.unused_flags = 0x01}; + goodix_tls_read_image(dev, &payload, scan_on_read_img, ssm); } const guint8 fdt_switch_state_mode[] = { From 81ce132b0bf01079115f4c7128a0d29a62cb02be Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 21:53:25 +0200 Subject: [PATCH 41/57] Export reply toggle for fdt functions --- libfprint/drivers/goodixtls/goodix.c | 18 +++++++++--------- libfprint/drivers/goodixtls/goodix.h | 6 +++--- libfprint/drivers/goodixtls/goodix511.c | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index a734553b3..fc57ca337 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -574,7 +574,7 @@ void goodix_send_mcu_get_image(FpDevice* dev, guint8* payload, GoodixImageCallba } void goodix_send_mcu_switch_to_fdt_down(FpDevice *dev, guint8 *mode, - guint16 length, + guint16 length, gboolean reply, GDestroyNotify free_func, GoodixDefaultCallback callback, gpointer user_data) { @@ -587,17 +587,17 @@ void goodix_send_mcu_switch_to_fdt_down(FpDevice *dev, guint8 *mode, cb_info->user_data = user_data; goodix_send_protocol(dev, GOODIX_CMD_MCU_SWITCH_TO_FDT_DOWN, mode, length, - free_func, TRUE, 0, TRUE, goodix_receive_default, + free_func, TRUE, 0, reply, goodix_receive_default, cb_info); return; } goodix_send_protocol(dev, GOODIX_CMD_MCU_SWITCH_TO_FDT_DOWN, mode, length, - free_func, TRUE, 0, TRUE, NULL, NULL); + free_func, TRUE, 0, reply, NULL, NULL); } void goodix_send_mcu_switch_to_fdt_up(FpDevice *dev, guint8 *mode, - guint16 length, GDestroyNotify free_func, + guint16 length, gboolean reply, GDestroyNotify free_func, GoodixDefaultCallback callback, gpointer user_data) { GoodixCallbackInfo *cb_info; @@ -609,17 +609,17 @@ void goodix_send_mcu_switch_to_fdt_up(FpDevice *dev, guint8 *mode, cb_info->user_data = user_data; goodix_send_protocol(dev, GOODIX_CMD_MCU_SWITCH_TO_FDT_UP, mode, length, - free_func, TRUE, 0, TRUE, goodix_receive_default, + free_func, TRUE, 0, reply, goodix_receive_default, cb_info); return; } goodix_send_protocol(dev, GOODIX_CMD_MCU_SWITCH_TO_FDT_UP, mode, length, - free_func, TRUE, 0, TRUE, NULL, NULL); + free_func, TRUE, 0, reply, NULL, NULL); } void goodix_send_mcu_switch_to_fdt_mode(FpDevice *dev, guint8 *mode, - guint16 length, + guint16 length, gboolean reply, GDestroyNotify free_func, GoodixDefaultCallback callback, gpointer user_data) { @@ -632,13 +632,13 @@ void goodix_send_mcu_switch_to_fdt_mode(FpDevice *dev, guint8 *mode, cb_info->user_data = user_data; goodix_send_protocol(dev, GOODIX_CMD_MCU_SWITCH_TO_FDT_MODE, mode, length, - free_func, TRUE, 0, TRUE, goodix_receive_default, + free_func, TRUE, 0, reply, goodix_receive_default, cb_info); return; } goodix_send_protocol(dev, GOODIX_CMD_MCU_SWITCH_TO_FDT_MODE, mode, length, - free_func, TRUE, 0, TRUE, NULL, NULL); + free_func, TRUE, 0, reply, NULL, NULL); } void goodix_send_nav_0(FpDevice *dev, GoodixDefaultCallback callback, diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index 90a844ff7..1f1d51faf 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -141,18 +141,18 @@ void goodix_send_mcu_get_image(FpDevice *dev, guint8* payload, GoodixImageCallba gpointer user_data); void goodix_send_mcu_switch_to_fdt_down(FpDevice *dev, guint8 *mode, - guint16 length, + guint16 length, gboolean reply, GDestroyNotify free_func, GoodixDefaultCallback callback, gpointer user_data); void goodix_send_mcu_switch_to_fdt_up(FpDevice *dev, guint8 *mode, - guint16 length, GDestroyNotify free_func, + guint16 length, gboolean reply, GDestroyNotify free_func, GoodixDefaultCallback callback, gpointer user_data); void goodix_send_mcu_switch_to_fdt_mode(FpDevice *dev, guint8 *mode, - guint16 length, + guint16 length, gboolean reply, GDestroyNotify free_func, GoodixDefaultCallback callback, gpointer user_data); diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index a7b073b9a..890d65b9f 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -627,13 +627,13 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) case SCAN_STAGE_SWITCH_TO_FDT_MODE: goodix_send_mcu_switch_to_fdt_mode(dev, (guint8*) fdt_switch_state_mode, - sizeof(fdt_switch_state_mode), NULL, + sizeof(fdt_switch_state_mode), TRUE, NULL, check_none_cmd, ssm); break; case SCAN_STAGE_SWITCH_TO_FDT_DOWN: goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down, - sizeof(fdt_switch_state_down), NULL, + sizeof(fdt_switch_state_down), TRUE, NULL, check_none_cmd, ssm); break; case SCAN_STAGE_GET_IMG: From 15081d44ce1cf70649b19e0ed8602da8851b6879 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 21:54:41 +0200 Subject: [PATCH 42/57] Unlist 521d from hwdb file --- libfprint/fprint-list-udev-hwdb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libfprint/fprint-list-udev-hwdb.c b/libfprint/fprint-list-udev-hwdb.c index c8230e595..890065e56 100644 --- a/libfprint/fprint-list-udev-hwdb.c +++ b/libfprint/fprint-list-udev-hwdb.c @@ -81,7 +81,6 @@ static const FpIdEntry whitelist_id_table[] = { { .vid = 0x27c6, .pid = 0x5042 }, { .vid = 0x27c6, .pid = 0x5117 }, { .vid = 0x27c6, .pid = 0x5201 }, - { .vid = 0x27c6, .pid = 0x521d }, { .vid = 0x27c6, .pid = 0x5301 }, { .vid = 0x27c6, .pid = 0x530c }, { .vid = 0x27c6, .pid = 0x532d }, From c4a3aade73452e5c05402e2690580d533a52a658 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 21:59:33 +0200 Subject: [PATCH 43/57] Added goodix52xd driver --- libfprint/drivers/goodixtls/goodix52xd.c | 846 +++++++++++++++++++++++ libfprint/drivers/goodixtls/goodix52xd.h | 76 ++ libfprint/meson.build | 2 + meson.build | 2 + 4 files changed, 926 insertions(+) create mode 100644 libfprint/drivers/goodixtls/goodix52xd.c create mode 100644 libfprint/drivers/goodixtls/goodix52xd.h diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c new file mode 100644 index 000000000..80d45ac9b --- /dev/null +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -0,0 +1,846 @@ +// Goodix Tls driver for libfprint + +// Copyright (C) 2021 Alexander Meiler +// Copyright (C) 2021 Matthieu CHARETTE +// Copyright (C) 2021 Michael Teuscher + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#include "fp-device.h" +#include "fp-image-device.h" +#include "fp-image.h" +#include "fpi-assembling.h" +#include "fpi-context.h" +#include "fpi-image-device.h" +#include "fpi-image.h" +#include "fpi-ssm.h" +#include "glibconfig.h" +#include "gusb/gusb-device.h" +#include +#include +#define FP_COMPONENT "goodixtls52xd" + +#include +#include + +#include "drivers_api.h" +#include "goodix.h" +#include "goodix_proto.h" +#include "goodix52xd.h" + +#include + +#define GOODIX52XD_WIDTH 64 +#define GOODIX52XD_HEIGHT 80 +#define GOODIX52XD_SCAN_WIDTH 64 +#define GOODIX52XD_FRAME_SIZE (GOODIX52XD_WIDTH * GOODIX52XD_HEIGHT) +// For every 4 pixels there are 6 bytes and there are 8 extra start bytes and 5 +// extra end +#define GOODIX52XD_RAW_FRAME_SIZE \ + (GOODIX52XD_HEIGHT * GOODIX52XD_SCAN_WIDTH) / 4 * 6 +#define GOODIX52XD_CAP_FRAMES 10 // Number of frames we capture per swipe + +typedef unsigned short Goodix52xdPix; + +struct _FpiDeviceGoodixTls52XD { + FpiDeviceGoodixTls parent; + + guint8* otp; + + GSList* frames; + + Goodix52xdPix empty_img[GOODIX52XD_FRAME_SIZE]; +}; + +G_DECLARE_FINAL_TYPE(FpiDeviceGoodixTls52XD, fpi_device_goodixtls52xd, FPI, + DEVICE_GOODIXTLS52XD, FpiDeviceGoodixTls); + +G_DEFINE_TYPE(FpiDeviceGoodixTls52XD, fpi_device_goodixtls52xd, + FPI_TYPE_DEVICE_GOODIXTLS); + +// ---- ACTIVE SECTION START ---- + +enum activate_states { + ACTIVATE_READ_AND_NOP, + ACTIVATE_ENABLE_CHIP, + ACTIVATE_NOP, + ACTIVATE_CHECK_FW_VER, + ACTIVATE_CHECK_PSK, + ACTIVATE_RESET, + ACTIVATE_SET_MCU_IDLE, + ACTIVATE_SET_MCU_CONFIG, + ACTIVATE_NUM_STATES, +}; + +static void check_none(FpDevice *dev, gpointer user_data, GError *error) { + if (error) { + fpi_ssm_mark_failed(user_data, error); + return; + } + + fpi_ssm_next_state(user_data); +} + +static void check_firmware_version(FpDevice *dev, gchar *firmware, + gpointer user_data, GError *error) { + if (error) { + fpi_ssm_mark_failed(user_data, error); + return; + } + + fp_dbg("Device firmware: \"%s\"", firmware); + g_print("%s\n", firmware); + + if (strcmp(firmware, GOODIX_52XD_FIRMWARE_VERSION)) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device firmware: \"%s\"", firmware); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fpi_ssm_next_state(user_data); +} + +static void check_reset(FpDevice *dev, gboolean success, guint16 number, + gpointer user_data, GError *error) { + if (error) { + fpi_ssm_mark_failed(user_data, error); + return; + } + + if (!success) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to reset device"); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fp_dbg("Device reset number: %d", number); + + if (number != GOODIX_52XD_RESET_NUMBER) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device reset number: %d", number); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fpi_ssm_next_state(user_data); +} + +static void check_preset_psk_read(FpDevice *dev, gboolean success, + guint32 flags, guint8 *psk, guint16 length, + gpointer user_data, GError *error) { + g_autofree gchar *psk_str = data_to_str(psk, length); + + if (error) { + fpi_ssm_mark_failed(user_data, error); + return; + } + + if (!success) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to read PSK from device"); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fp_dbg("Device PSK: 0x%s", psk_str); + fp_dbg("Device PSK flags: 0x%08x", flags); + + if (flags != GOODIX_52XD_PSK_FLAGS) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device PSK flags: 0x%08x", flags); + fpi_ssm_mark_failed(user_data, error); + return; + } + + if (length != sizeof(goodix_52xd_psk_0)) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device PSK: 0x%s", psk_str); + fpi_ssm_mark_failed(user_data, error); + return; + } + + if (memcmp(psk, goodix_52xd_psk_0, sizeof(goodix_52xd_psk_0))) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device PSK: 0x%s", psk_str); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fpi_ssm_next_state(user_data); +} +static void check_idle(FpDevice* dev, gpointer user_data, GError* err) +{ + + if (err) { + fpi_ssm_mark_failed(user_data, err); + return; + } + fpi_ssm_next_state(user_data); +} +static void check_config_upload(FpDevice* dev, gboolean success, + gpointer user_data, GError* error) +{ + if (error) { + fpi_ssm_mark_failed(user_data, error); + } + else if (!success) { + fpi_ssm_mark_failed(user_data, + g_error_new(FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO, + "failed to upload mcu config")); + } + else { + fpi_ssm_next_state(user_data); + } +} +static void check_powerdown_scan_freq(FpDevice* dev, gboolean success, + gpointer user_data, GError* error) +{ + if (error) { + fpi_ssm_mark_failed(user_data, error); + } + else if (!success) { + fpi_ssm_mark_failed(user_data, + g_error_new(FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO, + "failed to set powerdown freq")); + } + fpi_ssm_next_state(user_data); +} + +enum otp_write_states { + OTP_WRITE_1, + OTP_WRITE_2, + + OTP_WRITE_NUM, +}; + +static void otp_write_run(FpiSsm* ssm, FpDevice* dev) +{ + FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(dev); + switch (fpi_ssm_get_cur_state(ssm)) { + case OTP_WRITE_1: + guint8 sensor1[] = {0x0a, 0x02}; + goodix_send_write_sensor_register( + dev, 0x022c, sensor1, check_none, + ssm); + break; + case OTP_WRITE_2: + guint8 sensor2[] = {0x0a, 0x03}; + goodix_send_write_sensor_register( + dev, 0x022c, sensor2, check_none, + ssm); + fpi_ssm_next_state(ssm); + break; + } +} + +static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + /*if (len < 64) { + fpi_ssm_mark_failed(ssm, g_error_new(FP_DEVICE_ERROR, + FP_DEVICE_ERROR_DATA_INVALID, + "OTP is invalid (len: %d)", 64)); + return; + } + self->otp = malloc(64); + memcpy(self->otp, data, len);*/ + FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(dev); + + FpiSsm* otp_ssm = fpi_ssm_new(dev, otp_write_run, 3); + fpi_ssm_start_subsm(ssm, otp_ssm); +} + +static void activate_run_state(FpiSsm* ssm, FpDevice* dev) +{ + + switch (fpi_ssm_get_cur_state(ssm)) { + case ACTIVATE_READ_AND_NOP: + g_print("Read and NO OP\n"); + // Nop seems to clear the previous command buffer. But we are + // unable to do so. + goodix_start_read_loop(dev); + goodix_send_nop(dev, check_none, ssm); + break; + + case ACTIVATE_ENABLE_CHIP: + g_print("Enable Chip\n"); + goodix_send_enable_chip(dev, TRUE, check_none, ssm); + break; + + case ACTIVATE_NOP: + g_print("NO OP\n"); + goodix_send_nop(dev, check_none, ssm); + break; + + case ACTIVATE_CHECK_FW_VER: + g_print("Checking FW\n"); + goodix_send_firmware_version(dev, check_firmware_version, ssm); + break; + + case ACTIVATE_CHECK_PSK: + g_print("Checking PSK\n"); + goodix_send_preset_psk_read(dev, GOODIX_52XD_PSK_FLAGS, 32, + check_preset_psk_read, ssm); + break; + + case ACTIVATE_RESET: + g_print("Reset Device\n"); + goodix_send_reset(dev, TRUE, 20, check_reset, ssm); + break; + + case ACTIVATE_SET_MCU_IDLE: + g_print("Device IDLE\n"); + goodix_send_mcu_switch_to_idle_mode(dev, 20, check_idle, ssm); + break; + + case ACTIVATE_SET_MCU_CONFIG: + g_print("Uploading Device Config\n"); + goodix_send_upload_config_mcu(dev, goodix_52xd_config, + sizeof(goodix_52xd_config), NULL, + check_config_upload, ssm); + break; + } +} + +static void tls_activation_complete(FpDevice* dev, gpointer user_data, + GError* error) +{ + if (error) { + fp_err("failed to complete tls activation: %s", error->message); + return; + } + FpImageDevice* image_dev = FP_IMAGE_DEVICE(dev); + + fpi_image_device_activate_complete(image_dev, error); +} + +static void activate_complete(FpiSsm* ssm, FpDevice* dev, GError* error) +{ + G_DEBUG_HERE(); + if (!error) + goodix_tls(dev, tls_activation_complete, NULL); + else { + fp_err("failed during activation: %s (code: %d)", error->message, + error->code); + fpi_image_device_activate_complete(FP_IMAGE_DEVICE(dev), error); + } +} + +// ---- ACTIVE SECTION END ---- + +// ----------------------------------------------------------------------------- + +// ---- SCAN SECTION START ---- + +enum SCAN_STAGES { + SCAN_STAGE_SWITCH_TO_FDT_DOWN, + SCAN_STAGE_SWITCH_TO_FDT_MODE, + SCAN_STAGE_GET_IMG, + + SCAN_STAGE_NUM, +}; + +static void check_none_cmd(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + g_print("CHECK NONE FAILED\n"); + fpi_ssm_mark_failed(ssm, err); + return; + } + g_print("CHECK NONE SUCCESS\n"); + fpi_ssm_next_state(ssm); +} + +static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, + struct fpi_frame* frame, unsigned int x, + unsigned int y) +{ + return frame->data[x + y * GOODIX52XD_WIDTH]; +} + +// Bitdepth is 12, but we have to fit it in a byte +static unsigned char squash(int v) { return v / 16; } + +static void decode_frame(Goodix52xdPix frame[GOODIX52XD_FRAME_SIZE], + const guint8* raw_frame) +{ + Goodix52xdPix uncropped[GOODIX52XD_SCAN_WIDTH * GOODIX52XD_HEIGHT]; + Goodix52xdPix* pix = uncropped; + for (int i = 0; i < GOODIX52XD_RAW_FRAME_SIZE; i += 6) { + const guint8* chunk = raw_frame + i; + *pix++ = ((chunk[0] & 0xf) << 8) + chunk[1]; + *pix++ = (chunk[3] << 4) + (chunk[0] >> 4); + *pix++ = ((chunk[5] & 0xf) << 8) + chunk[2]; + *pix++ = (chunk[4] << 4) + (chunk[5] >> 4); + } + + for (int y = 0; y != GOODIX52XD_HEIGHT; ++y) { + for (int x = 0; x != GOODIX52XD_WIDTH; ++x) { + const int idx = x + y * GOODIX52XD_SCAN_WIDTH; + frame[x + y * GOODIX52XD_WIDTH] = uncropped[idx]; + } + } +} +static int goodix_cmp_short(const void* a, const void* b) +{ + return (int) (*(short*) a - *(short*) b); +} + +static void rotate_frame(Goodix52xdPix frame[GOODIX52XD_FRAME_SIZE]) +{ + Goodix52xdPix buff[GOODIX52XD_FRAME_SIZE]; + + for (int y = 0; y != GOODIX52XD_HEIGHT; ++y) { + for (int x = 0; x != GOODIX52XD_WIDTH; ++x) { + buff[x * GOODIX52XD_WIDTH + y] = frame[x + y * GOODIX52XD_WIDTH]; + } + } + memcpy(frame, buff, GOODIX52XD_FRAME_SIZE); +} +static void squash_frame(Goodix52xdPix* frame, guint8* squashed) +{ + for (int i = 0; i != GOODIX52XD_FRAME_SIZE; ++i) { + squashed[i] = squash(frame[i]); + } +} +/** + * @brief Squashes the 12 bit pixels of a raw frame into the 4 bit pixels used + * by libfprint. + * @details Borrowed from the elan driver. We reduce frames to + * within the max and min. + * + * @param frame + * @param squashed + */ +static void squash_frame_linear(Goodix52xdPix* frame, guint8* squashed) +{ + Goodix52xdPix min = 0xffff; + Goodix52xdPix max = 0; + + for (int i = 0; i != GOODIX52XD_FRAME_SIZE; ++i) { + const Goodix52xdPix pix = frame[i]; + if (pix < min) { + min = pix; + } + if (pix > max) { + max = pix; + } + } + + for (int i = 0; i != GOODIX52XD_FRAME_SIZE; ++i) { + const Goodix52xdPix pix = frame[i]; + if (pix - min == 0 || max - min == 0) { + squashed[i] = 0; + } + else { + squashed[i] = (pix - min) * 0xff / (max - min); + } + } +} + +/** + * @brief Subtracts the background from the frame + * + * @param frame + * @param background + */ +static gboolean postprocess_frame(Goodix52xdPix frame[GOODIX52XD_FRAME_SIZE], + Goodix52xdPix background[GOODIX52XD_FRAME_SIZE]) +{ + int sum = 0; + for (int i = 0; i != GOODIX52XD_FRAME_SIZE; ++i) { + Goodix52xdPix* og_px = frame + i; + Goodix52xdPix bg_px = background[i]; + if (bg_px > *og_px) { + *og_px = 0; + } + else { + *og_px -= bg_px; + } + *og_px = MAX(bg_px - *og_px, 0); + *og_px = MAX(*og_px - bg_px, 0); + sum += *og_px; + + } + if (sum == 0) { + fp_warn("frame darker than background, finger on scanner during " + "calibration?"); + } + return sum != 0; +} + +typedef struct _frame_processing_info { + FpiDeviceGoodixTls52XD* dev; + GSList** frames; + +} frame_processing_info; + +static void process_frame(Goodix52xdPix* raw_frame, frame_processing_info* info) +{ + struct fpi_frame* frame = + g_malloc(GOODIX52XD_FRAME_SIZE + sizeof(struct fpi_frame)); + //postprocess_frame(raw_frame, info->dev->empty_img); + squash_frame_linear(raw_frame, frame->data); + + *(info->frames) = g_slist_append(*(info->frames), frame); +} + +static void save_frame(FpiDeviceGoodixTls52XD* self, guint8* raw) +{ + Goodix52xdPix* frame = malloc(GOODIX52XD_FRAME_SIZE * sizeof(Goodix52xdPix)); + decode_frame(frame, raw); + self->frames = g_slist_append(self->frames, frame); +} + +static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + g_print("SCAN_ON_READ_IMG\n"); + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + + + FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(dev); + save_frame(self, data); + if (g_slist_length(self->frames) <= GOODIX52XD_CAP_FRAMES) { + fpi_ssm_jump_to_state(ssm, SCAN_STAGE_SWITCH_TO_FDT_MODE); + } + else { + GSList* raw_frames = g_slist_nth(self->frames, 1); + + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + struct fpi_frame_asmbl_ctx assembly_ctx; + assembly_ctx.frame_width = GOODIX52XD_WIDTH; + assembly_ctx.frame_height = GOODIX52XD_HEIGHT; + assembly_ctx.image_width = GOODIX52XD_WIDTH*3; + assembly_ctx.get_pixel = get_pix; + + GSList* frames = NULL; + frame_processing_info pinfo = {.dev = self, .frames = &frames}; + + g_slist_foreach(raw_frames, (GFunc) process_frame, &pinfo); + frames = g_slist_reverse(frames); + + fpi_do_movement_estimation(&assembly_ctx, frames); + FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); + + g_slist_free_full(frames, g_free); + g_slist_free_full(self->frames, g_free); + self->frames = g_slist_alloc(); + + fpi_image_device_image_captured(img_dev, img); + + + fpi_image_device_report_finger_status(img_dev, FALSE); + + fpi_ssm_next_state(ssm); + } +} + +gboolean +save_image_to_pgm2 (guchar *data, const char *path) +{ + FILE *fd = fopen (path, "w"); + size_t write_size = 7656; + int r; + + if (!fd) + { + g_warning ("could not open '%s' for writing: %d", path, errno); + return FALSE; + } + + r = fprintf (fd, "P2\n%d %d\n255\n", + GOODIX52XD_WIDTH, GOODIX52XD_HEIGHT); + if (r < 0) + { + fclose (fd); + g_critical ("pgm header write failed, error %d", r); + return FALSE; + } + + for (int i = 0; i < write_size; i += 1) { + r = fprintf(fd, "%d\n", data[i]); + } + fclose (fd); + g_debug ("written to '%s'", path); + + return TRUE; +} + +gboolean +save_image_to_pgm (FpImage *img, const char *path) +{ + FILE *fd = fopen (path, "w"); + size_t write_size; + const guchar *data = fp_image_get_data (img, &write_size); + int r; + + if (!fd) + { + g_warning ("could not open '%s' for writing: %d", path, errno); + return FALSE; + } + + r = fprintf (fd, "P5 %d %d 255\n", + fp_image_get_width (img), fp_image_get_height (img)); + if (r < 0) + { + fclose (fd); + g_critical ("pgm header write failed, error %d", r); + return FALSE; + } + + r = fwrite (data, 1, write_size, fd); + if (r < write_size) + { + fclose (fd); + g_critical ("short write (%d)", r); + return FALSE; + } + + fclose (fd); + g_debug ("written to '%s'", path); + + return TRUE; +} + +enum scan_empty_img_state { + SCAN_EMPTY_NAV0, + SCAN_EMPTY_GET_IMG, + + SCAN_EMPTY_NUM, +}; + +static void on_scan_empty_img(FpDevice* dev, guint8* data, guint16 length, + gpointer ssm, GError* error) +{ + if (error) { + fpi_ssm_mark_failed(ssm, error); + return; + } + FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(dev); + decode_frame(self->empty_img, data); + fpi_ssm_next_state(ssm); +} +static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) +{ + + switch (fpi_ssm_get_cur_state(ssm)) { + case SCAN_EMPTY_NAV0: + goodix_send_nav_0(dev, check_none_cmd, ssm); + break; + + case SCAN_EMPTY_GET_IMG: + guint8 payload[] = {0x45, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; + goodix_tls_read_image(dev, &payload, on_scan_empty_img, ssm); + break; + } +} + +static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) +{ + fpi_ssm_start_subsm(ssm, fpi_ssm_new(dev, scan_empty_run, SCAN_EMPTY_NUM)); +} + +static void scan_get_img(FpDevice* dev, FpiSsm* ssm) +{ + guint8 payload[] = {0x45, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; + goodix_tls_read_image(dev, &payload, scan_on_read_img, ssm); +} + +const guint8 fdt_switch_state_mode_52xd[] = { + 0x0d, 0x01, 0x27, 0x01, 0x21, 0x01, 0x27, + 0x01, 0x23, 0x01, 0x8d, 0x8d, 0x86, 0x86, + 0x97, 0x97, 0x8f, 0x8f, 0x9b, 0x9b, 0x92, + 0x92, 0x96, 0x96, 0x8c, 0x8c, 0x01 +}; + +const guint8 fdt_switch_state_mode1_52xd[] = { + 0x0d, 0x01, 0x27, 0x01, 0x21, 0x01, 0x27, + 0x01, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 +}; + +const guint8 fdt_switch_state_down_52xd[] = { + 0x9c, 0x01, 0x27, 0x01, 0x21, 0x01, 0x21, + 0x01, 0x23, 0x01, 0x8d, 0x8d, 0x86, 0x86, + 0x97, 0x97, 0x8f, 0x8f, 0x9b, 0x9b, 0x92, + 0x92, 0x96, 0x96, 0x8c, 0x8c, 0x01, 0x00, + 0x05, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, + 0x00, 0xa3, 0x00, 0x00 +}; + +static void scan_run_state(FpiSsm* ssm, FpDevice* dev) +{ + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + + switch (fpi_ssm_get_cur_state(ssm)) { + + case SCAN_STAGE_SWITCH_TO_FDT_MODE: + g_print("SWITCH TO FDT MODE\n"); + goodix_send_mcu_switch_to_fdt_mode(dev, (guint8*) fdt_switch_state_mode_52xd, + sizeof(fdt_switch_state_mode_52xd), FALSE, NULL, + check_none_cmd, ssm); + break; + + case SCAN_STAGE_SWITCH_TO_FDT_DOWN: + g_print("SWITCH TO FDT DOWN\n"); + goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down_52xd, + sizeof(fdt_switch_state_down_52xd), FALSE, NULL, + check_none_cmd, ssm); + break; + case SCAN_STAGE_GET_IMG: + g_print("SWITCH TO GET IMAGE\n"); + fpi_image_device_report_finger_status(img_dev, TRUE); + // Set Sensotr Register first to get valid output + // device.write_sensor_register(0x022c, b"\x05\x03") + guint8 payload[] = {0x05, 0x03}; + goodix_send_write_sensor_register(dev, 0x022c, payload, write_sensor_complete, ssm); + //scan_get_img(dev, ssm); + break; + } +} + +static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) +{ + if (error) { + fp_err("failed to scan: %s (code: %d)", error->message, error->code); + return; + } + scan_get_img(dev, user_data); +} + +static void scan_complete(FpiSsm* ssm, FpDevice* dev, GError* error) +{ + if (error) { + fp_err("failed to scan: %s (code: %d)", error->message, error->code); + return; + } + g_print("finished scan!"); + fp_dbg("finished scan"); +} + +static void scan_start(FpiDeviceGoodixTls52XD* dev) +{ + fpi_ssm_start(fpi_ssm_new(FP_DEVICE(dev), scan_run_state, SCAN_STAGE_NUM), + scan_complete); +} + +// ---- SCAN SECTION END ---- + +// ---- DEV SECTION START ---- + +static void dev_init(FpImageDevice *img_dev) { + FpDevice *dev = FP_DEVICE(img_dev); + GError *error = NULL; + + if (goodix_dev_init(dev, &error)) { + fpi_image_device_open_complete(img_dev, error); + return; + } + + fpi_image_device_open_complete(img_dev, NULL); +} + +static void dev_deinit(FpImageDevice *img_dev) { + FpDevice *dev = FP_DEVICE(img_dev); + GError *error = NULL; + + if (goodix_dev_deinit(dev, &error)) { + fpi_image_device_close_complete(img_dev, error); + return; + } + + fpi_image_device_close_complete(img_dev, NULL); +} + +static void dev_activate(FpImageDevice *img_dev) { + FpDevice* dev = FP_DEVICE(img_dev); + + fpi_ssm_start(fpi_ssm_new(dev, activate_run_state, ACTIVATE_NUM_STATES), + activate_complete); +} + + + +static void dev_change_state(FpImageDevice* img_dev, FpiImageDeviceState state) +{ + FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(img_dev); + G_DEBUG_HERE(); + + if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON) { + scan_start(self); + } +} + +static void goodix52xd_reset_state(FpiDeviceGoodixTls52XD* self) {} + +static void dev_deactivate(FpImageDevice *img_dev) { + FpDevice* dev = FP_DEVICE(img_dev); + goodix_reset_state(dev); + GError* error = NULL; + goodix_shutdown_tls(dev, &error); + goodix52xd_reset_state(FPI_DEVICE_GOODIXTLS52XD(img_dev)); + fpi_image_device_deactivate_complete(img_dev, error); +} + +// ---- DEV SECTION END ---- + +static void fpi_device_goodixtls52xd_init(FpiDeviceGoodixTls52XD* self) +{ + self->frames = g_slist_alloc(); +} + +static void fpi_device_goodixtls52xd_class_init( + FpiDeviceGoodixTls52XDClass *class) { + FpiDeviceGoodixTlsClass *gx_class = FPI_DEVICE_GOODIXTLS_CLASS(class); + FpDeviceClass *dev_class = FP_DEVICE_CLASS(class); + FpImageDeviceClass *img_dev_class = FP_IMAGE_DEVICE_CLASS(class); + + gx_class->interface = GOODIX_52XD_INTERFACE; + gx_class->ep_in = GOODIX_52XD_EP_IN; + gx_class->ep_out = GOODIX_52XD_EP_OUT; + + dev_class->id = "goodixtls52xd"; + dev_class->full_name = "Goodix TLS Fingerprint Sensor 52XD"; + dev_class->type = FP_DEVICE_TYPE_USB; + dev_class->id_table = id_table; + + dev_class->scan_type = FP_SCAN_TYPE_PRESS; + + // TODO + img_dev_class->bz3_threshold = 24; + img_dev_class->img_width = GOODIX52XD_WIDTH; + img_dev_class->img_height = GOODIX52XD_HEIGHT; + + img_dev_class->img_open = dev_init; + img_dev_class->img_close = dev_deinit; + img_dev_class->activate = dev_activate; + img_dev_class->change_state = dev_change_state; + img_dev_class->deactivate = dev_deactivate; + + fpi_device_class_auto_initialize_features(dev_class); +} diff --git a/libfprint/drivers/goodixtls/goodix52xd.h b/libfprint/drivers/goodixtls/goodix52xd.h new file mode 100644 index 000000000..651f00767 --- /dev/null +++ b/libfprint/drivers/goodixtls/goodix52xd.h @@ -0,0 +1,76 @@ +// Goodix Tls driver for libfprint + +// Copyright (C) 2021 Alexander Meiler +// Copyright (C) 2021 Matthieu CHARETTE +// Copyright (C) 2021 Michael Teuscher + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#pragma once + +#define GOODIX_52XD_INTERFACE (0) +#define GOODIX_52XD_EP_IN (0x83 | FPI_USB_ENDPOINT_IN) +#define GOODIX_52XD_EP_OUT (0x1 | FPI_USB_ENDPOINT_OUT) + +#define GOODIX_52XD_FIRMWARE_VERSION ("GFUSB_GM168SEC_APP_10019") + +#define GOODIX_52XD_PSK_FLAGS (0xbb020001) + +#define GOODIX_52XD_RESET_NUMBER (2048) + +const guint8 goodix_52xd_psk_0[] = { + 0x66, 0x68, 0x7a, 0xad, 0xf8, 0x62, 0xbd, 0x77, 0x6c, 0x8f, 0xc1, + 0x8b, 0x8e, 0x9f, 0x8e, 0x20, 0x08, 0x97, 0x14, 0x85, 0x6e, 0xe2, + 0x33, 0xb3, 0x90, 0x2a, 0x59, 0x1d, 0x0d, 0x5f, 0x29, 0x25}; + +guint8 goodix_52xd_config[] = { + 0x70, 0x11, 0x60, 0x71, 0x2c, 0x9d, 0x2c, 0xc9, 0x1c, 0xe5, 0x18, + 0xfd, 0x00, 0xfd, 0x00, 0xfd, 0x03, 0xba, 0x00, 0x01, 0x80, 0xca, + 0x00, 0x08, 0x00, 0x84, 0x00, 0xbe, 0xc3, 0x86, 0x00, 0xb1, 0xb6, + 0x88, 0x00, 0xba, 0xba, 0x8a, 0x00, 0xb3, 0xb3, 0x8c, 0x00, 0xbc, + 0xbc, 0x8e, 0x00, 0xb1, 0xb1, 0x90, 0x00, 0xbb, 0xbb, 0x92, 0x00, + 0xb1, 0xb1, 0x94, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x98, + 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, + 0xd4, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x01, 0x05, 0xd0, 0x00, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x72, 0x00, 0x78, 0x56, 0x74, 0x00, 0x34, 0x12, 0x20, + 0x00, 0x10, 0x40, 0x2a, 0x01, 0x02, 0x04, 0x22, 0x00, 0x01, 0x20, + 0x24, 0x00, 0x32, 0x00, 0x80, 0x00, 0x01, 0x00, 0x5c, 0x00, 0x01, + 0x01, 0x56, 0x00, 0x24, 0x20, 0x58, 0x00, 0x01, 0x02, 0x32, 0x00, + 0x04, 0x02, 0x66, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x58, 0x82, + 0x00, 0x7f, 0x08, 0x2a, 0x01, 0x82, 0x07, 0x22, 0x00, 0x01, 0x20, + 0x24, 0x00, 0x14, 0x00, 0x80, 0x00, 0x01, 0x40, 0x5c, 0x00, 0xea, + 0x00, 0x56, 0x00, 0x06, 0x14, 0x58, 0x00, 0x04, 0x02, 0x32, 0x00, + 0x0c, 0x02, 0x66, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x58, 0x82, + 0x00, 0x80, 0x08, 0x2a, 0x01, 0x08, 0x00, 0x5c, 0x00, 0x01, 0x01, + 0x54, 0x00, 0x00, 0x01, 0x62, 0x00, 0x08, 0x04, 0x64, 0x00, 0x10, + 0x00, 0x66, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x58, 0x2a, 0x01, + 0x08, 0x00, 0x5c, 0x00, 0xe8, 0x00, 0x52, 0x00, 0x08, 0x00, 0x54, + 0x00, 0x00, 0x01, 0x66, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x58, + 0x20, 0xc5, 0x0e}; + +static const FpIdEntry id_table[] = { + {.vid = 0x27c6, .pid = 0x521d}, + {.vid = 0, .pid = 0, .driver_data = 0}, +}; + +static void check_mcu_pov_image(FpDevice* dev, gboolean success, + gpointer user_data, GError* error); + + static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) ; + gboolean +save_image_to_pgm (FpImage *img, const char *path); +gboolean +save_image_to_pgm2 (guchar *data, const char *path); \ No newline at end of file diff --git a/libfprint/meson.build b/libfprint/meson.build index 42338dc74..626e34123 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -141,6 +141,8 @@ driver_sources = { [ 'drivers/goodixmoc/goodix.c', 'drivers/goodixmoc/goodix_proto.c' ], 'goodixtls511' : [ 'drivers/goodixtls/goodix511.c' ], + 'goodixtls52xd' : + [ 'drivers/goodixtls/goodix52xd.c' ], } helper_sources = { diff --git a/meson.build b/meson.build index 1324d40f7..b30cced16 100644 --- a/meson.build +++ b/meson.build @@ -124,6 +124,7 @@ default_drivers = [ 'upekts', 'goodixmoc', 'goodixtls511', + 'goodixtls52xd', 'nb1010', # SPI @@ -158,6 +159,7 @@ driver_helper_mapping = { 'uru4000' : [ 'nss' ], 'elanspi' : [ 'udev' ], 'goodixtls511' : [ 'goodixtls' ], + 'goodixtls52xd' : [ 'goodixtls' ], 'virtual_image' : [ 'virtual' ], 'virtual_device' : [ 'virtual' ], 'virtual_device_storage' : [ 'virtual' ], From 00d71f6f0d47635bc120380bd8cd0e1a3da7b89c Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 22:03:32 +0200 Subject: [PATCH 44/57] Change sensor write payload --- libfprint/drivers/goodixtls/goodix52xd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c index 80d45ac9b..a6d6cda6a 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.c +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -715,11 +715,8 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) case SCAN_STAGE_GET_IMG: g_print("SWITCH TO GET IMAGE\n"); fpi_image_device_report_finger_status(img_dev, TRUE); - // Set Sensotr Register first to get valid output - // device.write_sensor_register(0x022c, b"\x05\x03") - guint8 payload[] = {0x05, 0x03}; - goodix_send_write_sensor_register(dev, 0x022c, payload, write_sensor_complete, ssm); - //scan_get_img(dev, ssm); + guint16 payload = {0x05, 0x03}; + goodix_send_write_sensor_register(dev, 556, payload, write_sensor_complete, ssm); break; } } From 253343dcaea8f6441cbce1162d6d75eb363ccab4 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 22:04:41 +0200 Subject: [PATCH 45/57] Set offset to 0 --- libfprint/drivers/goodixtls/goodix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index fc57ca337..6f2bdc018 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -987,7 +987,8 @@ void goodix_send_preset_psk_read(FpDevice *dev, guint32 flags, guint16 length, GoodixPresetPskReadCallback callback, gpointer user_data) { GoodixPresetPsk payload = {.flags = GUINT32_TO_LE(flags), - .length = GUINT32_TO_LE(length)}; + .length = GUINT32_TO_LE(length), + .offset = GUINT16_TO_LE(0)}; GoodixCallbackInfo *cb_info; if (callback) { From 900d495e296e7c06dc013414d57a32301abf893f Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 22:44:11 +0200 Subject: [PATCH 46/57] Added PSK Response object --- libfprint/drivers/goodixtls/goodix_proto.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libfprint/drivers/goodixtls/goodix_proto.h b/libfprint/drivers/goodixtls/goodix_proto.h index 082461644..8a537da8d 100644 --- a/libfprint/drivers/goodixtls/goodix_proto.h +++ b/libfprint/drivers/goodixtls/goodix_proto.h @@ -115,6 +115,11 @@ typedef struct __attribute__((__packed__)) _GoodixPresetPsk { guint32 flags; } GoodixPresetPsk; +typedef struct __attribute__((__packed__)) _GoodixPresetPskResponse { + guint32 flags; + guint32 length; +} GoodixPresetPskResponse; + typedef struct __attribute__((__packed__)) _GoodixDefault { guint8 unused_flags; guint8 : 8; From d9da6f830924cc2f908c88dc33ff1e45487bfa07 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 22:44:38 +0200 Subject: [PATCH 47/57] Fix Sensor Register Write & expose mcu get image payload --- libfprint/drivers/goodixtls/goodix.c | 33 ++++++++++++------------ libfprint/drivers/goodixtls/goodix.h | 4 +-- libfprint/drivers/goodixtls/goodix511.c | 4 +-- libfprint/drivers/goodixtls/goodix52xd.c | 20 ++------------ 4 files changed, 23 insertions(+), 38 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index 6f2bdc018..b4aadacbe 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -177,11 +177,10 @@ void goodix_receive_preset_psk_read(FpDevice *dev, guint8 *data, guint16 length, callback(dev, FALSE, 0x00000000, NULL, 0, cb_info->user_data, error); return; } - - psk_len = - GUINT32_FROM_LE(((GoodixPresetPsk *)(data + sizeof(guint8)))->length); - - if (length < psk_len + sizeof(guint8) + sizeof(GoodixPresetPsk)) { + + GoodixPresetPskResponse* response = data + sizeof(guint8); + psk_len = response->length; + if (length < psk_len + sizeof(guint8) + sizeof(GoodixPresetPskResponse)) { g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid preset PSK read reply length: %d", length); callback(dev, FALSE, 0x00000000, NULL, 0, cb_info->user_data, error); @@ -189,8 +188,8 @@ void goodix_receive_preset_psk_read(FpDevice *dev, guint8 *data, guint16 length, } callback(dev, TRUE, - GUINT32_FROM_LE(((GoodixPresetPsk *)(data + sizeof(guint8)))->flags), - data + sizeof(guint8) + sizeof(GoodixPresetPsk), psk_len, + GUINT32_FROM_LE(response->flags), + data + sizeof(guint8) + sizeof(GoodixPresetPskResponse), psk_len, cb_info->user_data, NULL); } @@ -551,25 +550,27 @@ void goodix_send_nop(FpDevice *dev, GoodixNoneCallback callback, goodix_receive_done(dev, NULL, 0, NULL); } -void goodix_send_mcu_get_image(FpDevice* dev, guint8* payload, GoodixImageCallback callback, +void goodix_send_mcu_get_image(FpDevice* dev, guint8* payload, guint16 length, GoodixImageCallback callback, gpointer user_data) { GoodixCallbackInfo* cb_info; + // I want to remove this static value into the respective sub-drivers + if (callback) { cb_info = malloc(sizeof(GoodixCallbackInfo)); cb_info->callback = G_CALLBACK(callback); cb_info->user_data = user_data; - goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, (guint8*) &payload, - sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, TRUE, + goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, payload, + length, NULL, TRUE, GOODIX_TIMEOUT, TRUE, goodix_receive_default, cb_info); return; } - goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, (guint8*) &payload, - sizeof(payload), NULL, TRUE, GOODIX_TIMEOUT, TRUE, + goodix_send_protocol(dev, GOODIX_CMD_MCU_GET_IMAGE, payload, + length, NULL, TRUE, GOODIX_TIMEOUT, TRUE, NULL, NULL); } @@ -693,8 +694,8 @@ void goodix_send_write_sensor_register(FpDevice *dev, guint16 address, // Only support one address and one value GoodixWriteSensorRegister payload = {.multiples = FALSE, - .address = GUINT16_TO_LE(address), - .value = GUINT16_TO_LE(value)}; + .address = address, + .value = value}; GoodixCallbackInfo *cb_info; if (callback) { @@ -1315,7 +1316,7 @@ static void goodix_tls_ready_image_handler(FpDevice* dev, guint8* data, g_free(cb_info); } -void goodix_tls_read_image(FpDevice* dev, guint8* payload, GoodixImageCallback callback, +void goodix_tls_read_image(FpDevice* dev, guint8* payload, guint16 length, GoodixImageCallback callback, gpointer user_data) { g_assert(callback); @@ -1324,7 +1325,7 @@ void goodix_tls_read_image(FpDevice* dev, guint8* payload, GoodixImageCallback c cb_info->callback = G_CALLBACK(callback); cb_info->user_data = user_data; - goodix_send_mcu_get_image(dev, payload, goodix_tls_ready_image_handler, cb_info); + goodix_send_mcu_get_image(dev, payload, length, goodix_tls_ready_image_handler, cb_info); } // ---- TLS SECTION END ---- diff --git a/libfprint/drivers/goodixtls/goodix.h b/libfprint/drivers/goodixtls/goodix.h index 1f1d51faf..bd2e5e93c 100644 --- a/libfprint/drivers/goodixtls/goodix.h +++ b/libfprint/drivers/goodixtls/goodix.h @@ -137,7 +137,7 @@ void goodix_send_protocol(FpDevice *dev, guint8 cmd, guint8 *payload, void goodix_send_nop(FpDevice *dev, GoodixNoneCallback callback, gpointer user_data); -void goodix_send_mcu_get_image(FpDevice *dev, guint8* payload, GoodixImageCallback callback, +void goodix_send_mcu_get_image(FpDevice *dev, guint8* payload, guint16 length, GoodixImageCallback callback, gpointer user_data); void goodix_send_mcu_switch_to_fdt_down(FpDevice *dev, guint8 *mode, @@ -246,7 +246,7 @@ void goodix_tls(FpDevice* dev, GoodixNoneCallback callback, gpointer user_data); gboolean goodix_shutdown_tls(FpDevice* dev, GError** error); -void goodix_tls_read_image(FpDevice* dev, guint8* payload, GoodixImageCallback callback, +void goodix_tls_read_image(FpDevice* dev, guint8* payload, guint16 length, GoodixImageCallback callback, gpointer user_data); void goodix_tls_decrypt_image(FpDevice* dev, guint8** data, guint16* len); diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 890d65b9f..7e38b3caf 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -593,7 +593,7 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) case SCAN_EMPTY_GET_IMG: GoodixDefault payload = {.unused_flags = 0x01}; - goodix_tls_read_image(dev, &payload, on_scan_empty_img, ssm); + goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); break; } } @@ -606,7 +606,7 @@ static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { GoodixDefault payload = {.unused_flags = 0x01}; - goodix_tls_read_image(dev, &payload, scan_on_read_img, ssm); + goodix_tls_read_image(dev, &payload, sizeof(payload), scan_on_read_img, ssm); } const guint8 fdt_switch_state_mode[] = { diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c index a6d6cda6a..a2276cd94 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.c +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -101,7 +101,6 @@ static void check_firmware_version(FpDevice *dev, gchar *firmware, } fp_dbg("Device firmware: \"%s\"", firmware); - g_print("%s\n", firmware); if (strcmp(firmware, GOODIX_52XD_FIRMWARE_VERSION)) { g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, @@ -273,7 +272,6 @@ static void activate_run_state(FpiSsm* ssm, FpDevice* dev) switch (fpi_ssm_get_cur_state(ssm)) { case ACTIVATE_READ_AND_NOP: - g_print("Read and NO OP\n"); // Nop seems to clear the previous command buffer. But we are // unable to do so. goodix_start_read_loop(dev); @@ -281,38 +279,31 @@ static void activate_run_state(FpiSsm* ssm, FpDevice* dev) break; case ACTIVATE_ENABLE_CHIP: - g_print("Enable Chip\n"); goodix_send_enable_chip(dev, TRUE, check_none, ssm); break; case ACTIVATE_NOP: - g_print("NO OP\n"); goodix_send_nop(dev, check_none, ssm); break; case ACTIVATE_CHECK_FW_VER: - g_print("Checking FW\n"); goodix_send_firmware_version(dev, check_firmware_version, ssm); break; case ACTIVATE_CHECK_PSK: - g_print("Checking PSK\n"); goodix_send_preset_psk_read(dev, GOODIX_52XD_PSK_FLAGS, 32, check_preset_psk_read, ssm); break; case ACTIVATE_RESET: - g_print("Reset Device\n"); goodix_send_reset(dev, TRUE, 20, check_reset, ssm); break; case ACTIVATE_SET_MCU_IDLE: - g_print("Device IDLE\n"); goodix_send_mcu_switch_to_idle_mode(dev, 20, check_idle, ssm); break; case ACTIVATE_SET_MCU_CONFIG: - g_print("Uploading Device Config\n"); goodix_send_upload_config_mcu(dev, goodix_52xd_config, sizeof(goodix_52xd_config), NULL, check_config_upload, ssm); @@ -362,11 +353,9 @@ static void check_none_cmd(FpDevice* dev, guint8* data, guint16 len, gpointer ssm, GError* err) { if (err) { - g_print("CHECK NONE FAILED\n"); fpi_ssm_mark_failed(ssm, err); return; } - g_print("CHECK NONE SUCCESS\n"); fpi_ssm_next_state(ssm); } @@ -514,7 +503,6 @@ static void save_frame(FpiDeviceGoodixTls52XD* self, guint8* raw) static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, gpointer ssm, GError* err) { - g_print("SCAN_ON_READ_IMG\n"); if (err) { fpi_ssm_mark_failed(ssm, err); return; @@ -654,7 +642,7 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) case SCAN_EMPTY_GET_IMG: guint8 payload[] = {0x45, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; - goodix_tls_read_image(dev, &payload, on_scan_empty_img, ssm); + goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); break; } } @@ -667,7 +655,7 @@ static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { guint8 payload[] = {0x45, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; - goodix_tls_read_image(dev, &payload, scan_on_read_img, ssm); + goodix_tls_read_image(dev, &payload, sizeof(payload), scan_on_read_img, ssm); } const guint8 fdt_switch_state_mode_52xd[] = { @@ -700,20 +688,17 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) switch (fpi_ssm_get_cur_state(ssm)) { case SCAN_STAGE_SWITCH_TO_FDT_MODE: - g_print("SWITCH TO FDT MODE\n"); goodix_send_mcu_switch_to_fdt_mode(dev, (guint8*) fdt_switch_state_mode_52xd, sizeof(fdt_switch_state_mode_52xd), FALSE, NULL, check_none_cmd, ssm); break; case SCAN_STAGE_SWITCH_TO_FDT_DOWN: - g_print("SWITCH TO FDT DOWN\n"); goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down_52xd, sizeof(fdt_switch_state_down_52xd), FALSE, NULL, check_none_cmd, ssm); break; case SCAN_STAGE_GET_IMG: - g_print("SWITCH TO GET IMAGE\n"); fpi_image_device_report_finger_status(img_dev, TRUE); guint16 payload = {0x05, 0x03}; goodix_send_write_sensor_register(dev, 556, payload, write_sensor_complete, ssm); @@ -736,7 +721,6 @@ static void scan_complete(FpiSsm* ssm, FpDevice* dev, GError* error) fp_err("failed to scan: %s (code: %d)", error->message, error->code); return; } - g_print("finished scan!"); fp_dbg("finished scan"); } From d4309eaa3d814cb14aee2b3d74a9c3e2f2096ed7 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Mon, 25 Oct 2021 22:48:25 +0200 Subject: [PATCH 48/57] Update project files --- .gitignore | 1 + .vscode/c_cpp_properties.json | 33 +++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 07d739953..220b6fe29 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o *.swp _build +test.sh \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index ab7ba7655..8b66fe39b 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,15 +1,20 @@ { - "configurations": [ - { - "name": "Linux", - "includePath": ["${workspaceFolder}/**"], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "gnu17", - "cppStandard": "gnu++14", - "intelliSenseMode": "linux-gcc-x64", - "compileCommands": "${workspaceFolder}/_build/compile_commands.json" - } - ], - "version": 4 -} + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "/usr/include/gusb-1", + "/usr/include/glib-2.0", + "/usr/lib64/glib-2.0/include" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64", + "compileCommands": "${workspaceFolder}/_build/compile_commands.json" + } + ], + "version": 4 +} \ No newline at end of file From 16623333725a1e8174a9c31de3ffdf5b546105ea Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Tue, 26 Oct 2021 00:43:02 +0200 Subject: [PATCH 49/57] Initial commit for 538d --- data/autosuspend.hwdb | 5 +- libfprint/drivers/goodixtls/goodix53xd.c | 750 +++++++++++++++++++++++ libfprint/drivers/goodixtls/goodix53xd.h | 70 +++ libfprint/meson.build | 2 + meson.build | 2 + 5 files changed, 828 insertions(+), 1 deletion(-) create mode 100644 libfprint/drivers/goodixtls/goodix53xd.c create mode 100644 libfprint/drivers/goodixtls/goodix53xd.h diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb index 74b1b82d4..6f6972c23 100644 --- a/data/autosuspend.hwdb +++ b/data/autosuspend.hwdb @@ -172,6 +172,10 @@ usb:v27C6p6A94* usb:v27C6p521D* ID_AUTOSUSPEND=1 +# Supported by libfprint driver goodixtls53xd +usb:v27C6p538D* + ID_AUTOSUSPEND=1 + # Supported by libfprint driver goodixtls511 usb:v27c6p5110* ID_AUTOSUSPEND=1 @@ -320,7 +324,6 @@ usb:v27C6p533C* usb:v27C6p5381* usb:v27C6p5385* usb:v27C6p538C* -usb:v27C6p538D* usb:v27C6p5395* usb:v27C6p5584* usb:v27C6p55A2* diff --git a/libfprint/drivers/goodixtls/goodix53xd.c b/libfprint/drivers/goodixtls/goodix53xd.c new file mode 100644 index 000000000..0c5bf665f --- /dev/null +++ b/libfprint/drivers/goodixtls/goodix53xd.c @@ -0,0 +1,750 @@ +// Goodix Tls driver for libfprint + +// Copyright (C) 2021 Alexander Meiler +// Copyright (C) 2021 Matthieu CHARETTE +// Copyright (C) 2021 Michael Teuscher + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#include "fp-device.h" +#include "fp-image-device.h" +#include "fp-image.h" +#include "fpi-assembling.h" +#include "fpi-context.h" +#include "fpi-image-device.h" +#include "fpi-image.h" +#include "fpi-ssm.h" +#include "glibconfig.h" +#include "gusb/gusb-device.h" +#include +#include +#define FP_COMPONENT "goodixtls53xd" + +#include +#include + +#include "drivers_api.h" +#include "goodix.h" +#include "goodix_proto.h" +#include "goodix53xd.h" + +#include + +#define GOODIX53XD_WIDTH 64 +#define GOODIX53XD_HEIGHT 80 +#define GOODIX53XD_SCAN_WIDTH 64 +#define GOODIX53XD_FRAME_SIZE (GOODIX53XD_WIDTH * GOODIX53XD_HEIGHT) +// For every 4 pixels there are 6 bytes and there are 8 extra start bytes and 5 +// extra end +#define GOODIX53XD_RAW_FRAME_SIZE \ + (GOODIX53XD_HEIGHT * GOODIX53XD_SCAN_WIDTH) / 4 * 6 +#define GOODIX53XD_CAP_FRAMES 10 // Number of frames we capture per swipe + +typedef unsigned short Goodix53xdPix; + +struct _FpiDeviceGoodixTls53XD { + FpiDeviceGoodixTls parent; + + guint8* otp; + + GSList* frames; + + Goodix53xdPix empty_img[GOODIX53XD_FRAME_SIZE]; +}; + +G_DECLARE_FINAL_TYPE(FpiDeviceGoodixTls53XD, fpi_device_goodixtls53xd, FPI, + DEVICE_GOODIXTLS53XD, FpiDeviceGoodixTls); + +G_DEFINE_TYPE(FpiDeviceGoodixTls53XD, fpi_device_goodixtls53xd, + FPI_TYPE_DEVICE_GOODIXTLS); + +// ---- ACTIVE SECTION START ---- + +enum activate_states { + ACTIVATE_READ_AND_NOP, + ACTIVATE_ENABLE_CHIP, + ACTIVATE_NOP, + ACTIVATE_CHECK_FW_VER, + ACTIVATE_CHECK_PSK, + ACTIVATE_RESET, + ACTIVATE_SET_MCU_IDLE, + ACTIVATE_SET_MCU_CONFIG, + ACTIVATE_NUM_STATES, +}; + +static void check_none(FpDevice *dev, gpointer user_data, GError *error) { + if (error) { + fpi_ssm_mark_failed(user_data, error); + return; + } + + fpi_ssm_next_state(user_data); +} + +static void check_firmware_version(FpDevice *dev, gchar *firmware, + gpointer user_data, GError *error) { + if (error) { + fpi_ssm_mark_failed(user_data, error); + return; + } + + fp_dbg("Device firmware: \"%s\"", firmware); + + if (strcmp(firmware, GOODIX_53XD_FIRMWARE_VERSION)) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device firmware: \"%s\"", firmware); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fpi_ssm_next_state(user_data); +} + +static void check_reset(FpDevice *dev, gboolean success, guint16 number, + gpointer user_data, GError *error) { + if (error) { + fpi_ssm_mark_failed(user_data, error); + return; + } + + if (!success) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to reset device"); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fp_dbg("Device reset number: %d", number); + + if (number != GOODIX_53XD_RESET_NUMBER) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device reset number: %d", number); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fpi_ssm_next_state(user_data); +} + +static void check_preset_psk_read(FpDevice *dev, gboolean success, + guint32 flags, guint8 *psk, guint16 length, + gpointer user_data, GError *error) { + g_autofree gchar *psk_str = data_to_str(psk, length); + + if (error) { + fpi_ssm_mark_failed(user_data, error); + return; + } + + if (!success) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to read PSK from device"); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fp_dbg("Device PSK: 0x%s", psk_str); + fp_dbg("Device PSK flags: 0x%08x", flags); + + if (flags != GOODIX_53XD_PSK_FLAGS) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device PSK flags: 0x%08x", flags); + fpi_ssm_mark_failed(user_data, error); + return; + } + + if (length != sizeof(goodix_53xd_psk_0)) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device PSK: 0x%s", psk_str); + fpi_ssm_mark_failed(user_data, error); + return; + } + + if (memcmp(psk, goodix_53xd_psk_0, sizeof(goodix_53xd_psk_0))) { + g_set_error(&error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Invalid device PSK: 0x%s", psk_str); + fpi_ssm_mark_failed(user_data, error); + return; + } + + fpi_ssm_next_state(user_data); +} +static void check_idle(FpDevice* dev, gpointer user_data, GError* err) +{ + + if (err) { + fpi_ssm_mark_failed(user_data, err); + return; + } + fpi_ssm_next_state(user_data); +} +static void check_config_upload(FpDevice* dev, gboolean success, + gpointer user_data, GError* error) +{ + if (error) { + fpi_ssm_mark_failed(user_data, error); + } + else if (!success) { + fpi_ssm_mark_failed(user_data, + g_error_new(FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO, + "failed to upload mcu config")); + } + else { + fpi_ssm_next_state(user_data); + } +} +static void check_powerdown_scan_freq(FpDevice* dev, gboolean success, + gpointer user_data, GError* error) +{ + if (error) { + fpi_ssm_mark_failed(user_data, error); + } + else if (!success) { + fpi_ssm_mark_failed(user_data, + g_error_new(FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO, + "failed to set powerdown freq")); + } + fpi_ssm_next_state(user_data); +} + +enum otp_write_states { + OTP_WRITE_1, + OTP_WRITE_2, + + OTP_WRITE_NUM, +}; + +static void otp_write_run(FpiSsm* ssm, FpDevice* dev) +{ + FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(dev); + switch (fpi_ssm_get_cur_state(ssm)) { + case OTP_WRITE_1: + guint8 sensor1[] = {0x0a, 0x02}; + goodix_send_write_sensor_register( + dev, 0x022c, sensor1, check_none, + ssm); + break; + case OTP_WRITE_2: + guint8 sensor2[] = {0x0a, 0x03}; + goodix_send_write_sensor_register( + dev, 0x022c, sensor2, check_none, + ssm); + fpi_ssm_next_state(ssm); + break; + } +} + +static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + /*if (len < 64) { + fpi_ssm_mark_failed(ssm, g_error_new(FP_DEVICE_ERROR, + FP_DEVICE_ERROR_DATA_INVALID, + "OTP is invalid (len: %d)", 64)); + return; + } + self->otp = malloc(64); + memcpy(self->otp, data, len);*/ + FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(dev); + + FpiSsm* otp_ssm = fpi_ssm_new(dev, otp_write_run, 3); + fpi_ssm_start_subsm(ssm, otp_ssm); +} + +static void activate_run_state(FpiSsm* ssm, FpDevice* dev) +{ + + switch (fpi_ssm_get_cur_state(ssm)) { + case ACTIVATE_READ_AND_NOP: + // Nop seems to clear the previous command buffer. But we are + // unable to do so. + goodix_start_read_loop(dev); + goodix_send_nop(dev, check_none, ssm); + break; + + case ACTIVATE_ENABLE_CHIP: + goodix_send_enable_chip(dev, TRUE, check_none, ssm); + break; + + case ACTIVATE_NOP: + goodix_send_nop(dev, check_none, ssm); + break; + + case ACTIVATE_CHECK_FW_VER: + goodix_send_firmware_version(dev, check_firmware_version, ssm); + break; + + case ACTIVATE_CHECK_PSK: + goodix_send_preset_psk_read(dev, GOODIX_53XD_PSK_FLAGS, 32, + check_preset_psk_read, ssm); + break; + + case ACTIVATE_RESET: + goodix_send_reset(dev, TRUE, 20, check_reset, ssm); + break; + + case ACTIVATE_SET_MCU_IDLE: + goodix_send_mcu_switch_to_idle_mode(dev, 20, check_idle, ssm); + break; + + case ACTIVATE_SET_MCU_CONFIG: + goodix_send_upload_config_mcu(dev, goodix_53xd_config, + sizeof(goodix_53xd_config), NULL, + check_config_upload, ssm); + break; + } +} + +static void tls_activation_complete(FpDevice* dev, gpointer user_data, + GError* error) +{ + if (error) { + fp_err("failed to complete tls activation: %s", error->message); + return; + } + FpImageDevice* image_dev = FP_IMAGE_DEVICE(dev); + + fpi_image_device_activate_complete(image_dev, error); +} + +static void activate_complete(FpiSsm* ssm, FpDevice* dev, GError* error) +{ + G_DEBUG_HERE(); + if (!error) + goodix_tls(dev, tls_activation_complete, NULL); + else { + fp_err("failed during activation: %s (code: %d)", error->message, + error->code); + fpi_image_device_activate_complete(FP_IMAGE_DEVICE(dev), error); + } +} + +// ---- ACTIVE SECTION END ---- + +// ----------------------------------------------------------------------------- + +// ---- SCAN SECTION START ---- + +enum SCAN_STAGES { + SCAN_STAGE_SWITCH_TO_FDT_DOWN, + SCAN_STAGE_SWITCH_TO_FDT_MODE, + SCAN_STAGE_GET_IMG, + + SCAN_STAGE_NUM, +}; + +static void check_none_cmd(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + fpi_ssm_next_state(ssm); +} + +static unsigned char get_pix(struct fpi_frame_asmbl_ctx* ctx, + struct fpi_frame* frame, unsigned int x, + unsigned int y) +{ + return frame->data[x + y * GOODIX53XD_WIDTH]; +} + +// Bitdepth is 12, but we have to fit it in a byte +static unsigned char squash(int v) { return v / 16; } + +static void decode_frame(Goodix53xdPix frame[GOODIX53XD_FRAME_SIZE], + const guint8* raw_frame) +{ + Goodix53xdPix uncropped[GOODIX53XD_SCAN_WIDTH * GOODIX53XD_HEIGHT]; + Goodix53xdPix* pix = uncropped; + for (int i = 0; i < GOODIX53XD_RAW_FRAME_SIZE; i += 6) { + const guint8* chunk = raw_frame + i; + *pix++ = ((chunk[0] & 0xf) << 8) + chunk[1]; + *pix++ = (chunk[3] << 4) + (chunk[0] >> 4); + *pix++ = ((chunk[5] & 0xf) << 8) + chunk[2]; + *pix++ = (chunk[4] << 4) + (chunk[5] >> 4); + } + + for (int y = 0; y != GOODIX53XD_HEIGHT; ++y) { + for (int x = 0; x != GOODIX53XD_WIDTH; ++x) { + const int idx = x + y * GOODIX53XD_SCAN_WIDTH; + frame[x + y * GOODIX53XD_WIDTH] = uncropped[idx]; + } + } +} +static int goodix_cmp_short(const void* a, const void* b) +{ + return (int) (*(short*) a - *(short*) b); +} + +static void rotate_frame(Goodix53xdPix frame[GOODIX53XD_FRAME_SIZE]) +{ + Goodix53xdPix buff[GOODIX53XD_FRAME_SIZE]; + + for (int y = 0; y != GOODIX53XD_HEIGHT; ++y) { + for (int x = 0; x != GOODIX53XD_WIDTH; ++x) { + buff[x * GOODIX53XD_WIDTH + y] = frame[x + y * GOODIX53XD_WIDTH]; + } + } + memcpy(frame, buff, GOODIX53XD_FRAME_SIZE); +} +static void squash_frame(Goodix53xdPix* frame, guint8* squashed) +{ + for (int i = 0; i != GOODIX53XD_FRAME_SIZE; ++i) { + squashed[i] = squash(frame[i]); + } +} +/** + * @brief Squashes the 12 bit pixels of a raw frame into the 4 bit pixels used + * by libfprint. + * @details Borrowed from the elan driver. We reduce frames to + * within the max and min. + * + * @param frame + * @param squashed + */ +static void squash_frame_linear(Goodix53xdPix* frame, guint8* squashed) +{ + Goodix53xdPix min = 0xffff; + Goodix53xdPix max = 0; + + for (int i = 0; i != GOODIX53XD_FRAME_SIZE; ++i) { + const Goodix53xdPix pix = frame[i]; + if (pix < min) { + min = pix; + } + if (pix > max) { + max = pix; + } + } + + for (int i = 0; i != GOODIX53XD_FRAME_SIZE; ++i) { + const Goodix53xdPix pix = frame[i]; + if (pix - min == 0 || max - min == 0) { + squashed[i] = 0; + } + else { + squashed[i] = (pix - min) * 0xff / (max - min); + } + } +} + +/** + * @brief Subtracts the background from the frame + * + * @param frame + * @param background + */ +static gboolean postprocess_frame(Goodix53xdPix frame[GOODIX53XD_FRAME_SIZE], + Goodix53xdPix background[GOODIX53XD_FRAME_SIZE]) +{ + int sum = 0; + for (int i = 0; i != GOODIX53XD_FRAME_SIZE; ++i) { + Goodix53xdPix* og_px = frame + i; + Goodix53xdPix bg_px = background[i]; + if (bg_px > *og_px) { + *og_px = 0; + } + else { + *og_px -= bg_px; + } + *og_px = MAX(bg_px - *og_px, 0); + *og_px = MAX(*og_px - bg_px, 0); + sum += *og_px; + + } + if (sum == 0) { + fp_warn("frame darker than background, finger on scanner during " + "calibration?"); + } + return sum != 0; +} + +typedef struct _frame_processing_info { + FpiDeviceGoodixTls53XD* dev; + GSList** frames; + +} frame_processing_info; + +static void process_frame(Goodix53xdPix* raw_frame, frame_processing_info* info) +{ + struct fpi_frame* frame = + g_malloc(GOODIX53XD_FRAME_SIZE + sizeof(struct fpi_frame)); + //postprocess_frame(raw_frame, info->dev->empty_img); + squash_frame_linear(raw_frame, frame->data); + + *(info->frames) = g_slist_append(*(info->frames), frame); +} + +static void save_frame(FpiDeviceGoodixTls53XD* self, guint8* raw) +{ + Goodix53xdPix* frame = malloc(GOODIX53XD_FRAME_SIZE * sizeof(Goodix53xdPix)); + decode_frame(frame, raw); + self->frames = g_slist_append(self->frames, frame); +} + +static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + + + FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(dev); + save_frame(self, data); + if (g_slist_length(self->frames) <= GOODIX53XD_CAP_FRAMES) { + fpi_ssm_jump_to_state(ssm, SCAN_STAGE_SWITCH_TO_FDT_MODE); + } + else { + GSList* raw_frames = g_slist_nth(self->frames, 1); + + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + struct fpi_frame_asmbl_ctx assembly_ctx; + assembly_ctx.frame_width = GOODIX53XD_WIDTH; + assembly_ctx.frame_height = GOODIX53XD_HEIGHT; + assembly_ctx.image_width = GOODIX53XD_WIDTH*3; + assembly_ctx.get_pixel = get_pix; + + GSList* frames = NULL; + frame_processing_info pinfo = {.dev = self, .frames = &frames}; + + g_slist_foreach(raw_frames, (GFunc) process_frame, &pinfo); + frames = g_slist_reverse(frames); + + fpi_do_movement_estimation(&assembly_ctx, frames); + FpImage* img = fpi_assemble_frames(&assembly_ctx, frames); + + g_slist_free_full(frames, g_free); + g_slist_free_full(self->frames, g_free); + self->frames = g_slist_alloc(); + + fpi_image_device_image_captured(img_dev, img); + + + fpi_image_device_report_finger_status(img_dev, FALSE); + + fpi_ssm_next_state(ssm); + } +} + +enum scan_empty_img_state { + SCAN_EMPTY_NAV0, + SCAN_EMPTY_GET_IMG, + + SCAN_EMPTY_NUM, +}; + +static void on_scan_empty_img(FpDevice* dev, guint8* data, guint16 length, + gpointer ssm, GError* error) +{ + if (error) { + fpi_ssm_mark_failed(ssm, error); + return; + } + FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(dev); + decode_frame(self->empty_img, data); + fpi_ssm_next_state(ssm); +} +static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) +{ + + switch (fpi_ssm_get_cur_state(ssm)) { + case SCAN_EMPTY_NAV0: + goodix_send_nav_0(dev, check_none_cmd, ssm); + break; + + case SCAN_EMPTY_GET_IMG: + guint8 payload[] = {0x41, 0x03, 0xa5, 0x00, 0x9f, 0x00, 0xa5, 0x00, 0xa1, 0x00}; + goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); + break; + } +} + +static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) +{ + fpi_ssm_start_subsm(ssm, fpi_ssm_new(dev, scan_empty_run, SCAN_EMPTY_NUM)); +} + +static void scan_get_img(FpDevice* dev, FpiSsm* ssm) +{ + guint8 payload[] = {0x41, 0x03, 0xa5, 0x00, 0x9f, 0x00, 0xa5, 0x00, 0xa1, 0x00}; + goodix_tls_read_image(dev, &payload, sizeof(payload), scan_on_read_img, ssm); +} + +const guint8 fdt_switch_state_mode_53xd[] = { + 0x0d, 0x01, 0x28, 0x01, 0x22, 0x01, 0x28, 0x01, + 0x24, 0x01, 0x91, 0x91, 0x8b, 0x8b, 0x96, 0x96, + 0x91, 0x91, 0x98, 0x98, 0x90, 0x90, 0x92, 0x92, + 0x88, 0x88, 0x00 +}; + +const guint8 fdt_switch_state_down_53xd[] = { + 0x8c, 0x01, 0x28, 0x01, 0x22, 0x01, 0x28, 0x01, + 0x24, 0x01, 0x91, 0x91, 0x8b, 0x8b, 0x96, 0x96, + 0x91, 0x91, 0x98, 0x98, 0x90, 0x90, 0x92, 0x92, + 0x88, 0x88, 0x01 +}; + +static void scan_run_state(FpiSsm* ssm, FpDevice* dev) +{ + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + + switch (fpi_ssm_get_cur_state(ssm)) { + + case SCAN_STAGE_SWITCH_TO_FDT_MODE: + goodix_send_mcu_switch_to_fdt_mode(dev, (guint8*) fdt_switch_state_mode_53xd, + sizeof(fdt_switch_state_mode_53xd), FALSE, NULL, + check_none_cmd, ssm); + break; + + case SCAN_STAGE_SWITCH_TO_FDT_DOWN: + goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down_53xd, + sizeof(fdt_switch_state_down_53xd), FALSE, NULL, + check_none_cmd, ssm); + break; + case SCAN_STAGE_GET_IMG: + fpi_image_device_report_finger_status(img_dev, TRUE); + guint16 payload = {0x05, 0x03}; + goodix_send_write_sensor_register(dev, 556, payload, write_sensor_complete, ssm); + break; + } +} + +static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) +{ + if (error) { + fp_err("failed to scan: %s (code: %d)", error->message, error->code); + return; + } + scan_get_img(dev, user_data); +} + +static void scan_complete(FpiSsm* ssm, FpDevice* dev, GError* error) +{ + if (error) { + fp_err("failed to scan: %s (code: %d)", error->message, error->code); + return; + } + fp_dbg("finished scan"); +} + +static void scan_start(FpiDeviceGoodixTls53XD* dev) +{ + fpi_ssm_start(fpi_ssm_new(FP_DEVICE(dev), scan_run_state, SCAN_STAGE_NUM), + scan_complete); +} + +// ---- SCAN SECTION END ---- + +// ---- DEV SECTION START ---- + +static void dev_init(FpImageDevice *img_dev) { + FpDevice *dev = FP_DEVICE(img_dev); + GError *error = NULL; + + if (goodix_dev_init(dev, &error)) { + fpi_image_device_open_complete(img_dev, error); + return; + } + + fpi_image_device_open_complete(img_dev, NULL); +} + +static void dev_deinit(FpImageDevice *img_dev) { + FpDevice *dev = FP_DEVICE(img_dev); + GError *error = NULL; + + if (goodix_dev_deinit(dev, &error)) { + fpi_image_device_close_complete(img_dev, error); + return; + } + + fpi_image_device_close_complete(img_dev, NULL); +} + +static void dev_activate(FpImageDevice *img_dev) { + FpDevice* dev = FP_DEVICE(img_dev); + + fpi_ssm_start(fpi_ssm_new(dev, activate_run_state, ACTIVATE_NUM_STATES), + activate_complete); +} + + + +static void dev_change_state(FpImageDevice* img_dev, FpiImageDeviceState state) +{ + FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(img_dev); + G_DEBUG_HERE(); + + if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON) { + scan_start(self); + } +} + +static void goodix53xd_reset_state(FpiDeviceGoodixTls53XD* self) {} + +static void dev_deactivate(FpImageDevice *img_dev) { + FpDevice* dev = FP_DEVICE(img_dev); + goodix_reset_state(dev); + GError* error = NULL; + goodix_shutdown_tls(dev, &error); + goodix53xd_reset_state(FPI_DEVICE_GOODIXTLS53XD(img_dev)); + fpi_image_device_deactivate_complete(img_dev, error); +} + +// ---- DEV SECTION END ---- + +static void fpi_device_goodixtls53xd_init(FpiDeviceGoodixTls53XD* self) +{ + self->frames = g_slist_alloc(); +} + +static void fpi_device_goodixtls53xd_class_init( + FpiDeviceGoodixTls53XDClass *class) { + FpiDeviceGoodixTlsClass *gx_class = FPI_DEVICE_GOODIXTLS_CLASS(class); + FpDeviceClass *dev_class = FP_DEVICE_CLASS(class); + FpImageDeviceClass *img_dev_class = FP_IMAGE_DEVICE_CLASS(class); + + gx_class->interface = GOODIX_53XD_INTERFACE; + gx_class->ep_in = GOODIX_53XD_EP_IN; + gx_class->ep_out = GOODIX_53XD_EP_OUT; + + dev_class->id = "goodixtls53xd"; + dev_class->full_name = "Goodix TLS Fingerprint Sensor 53XD"; + dev_class->type = FP_DEVICE_TYPE_USB; + dev_class->id_table = id_table; + + dev_class->scan_type = FP_SCAN_TYPE_PRESS; + + // TODO + img_dev_class->bz3_threshold = 24; + img_dev_class->img_width = GOODIX53XD_WIDTH; + img_dev_class->img_height = GOODIX53XD_HEIGHT; + + img_dev_class->img_open = dev_init; + img_dev_class->img_close = dev_deinit; + img_dev_class->activate = dev_activate; + img_dev_class->change_state = dev_change_state; + img_dev_class->deactivate = dev_deactivate; + + fpi_device_class_auto_initialize_features(dev_class); +} diff --git a/libfprint/drivers/goodixtls/goodix53xd.h b/libfprint/drivers/goodixtls/goodix53xd.h new file mode 100644 index 000000000..bcbe5e98e --- /dev/null +++ b/libfprint/drivers/goodixtls/goodix53xd.h @@ -0,0 +1,70 @@ +// Goodix Tls driver for libfprint + +// Copyright (C) 2021 Alexander Meiler +// Copyright (C) 2021 Matthieu CHARETTE +// Copyright (C) 2021 Michael Teuscher + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#pragma once + +#define GOODIX_53XD_INTERFACE (0) +#define GOODIX_53XD_EP_IN (0x83 | FPI_USB_ENDPOINT_IN) +#define GOODIX_53XD_EP_OUT (0x1 | FPI_USB_ENDPOINT_OUT) + +#define GOODIX_53XD_FIRMWARE_VERSION ("GF5298_GM168SEC_APP_13016") + +#define GOODIX_53XD_PSK_FLAGS (0xbb020001) + +#define GOODIX_53XD_RESET_NUMBER (2048) + +const guint8 goodix_53xd_psk_0[] = { + 0x66, 0x68, 0x7a, 0xad, 0xf8, 0x62, 0xbd, 0x77, 0x6c, 0x8f, 0xc1, + 0x8b, 0x8e, 0x9f, 0x8e, 0x20, 0x08, 0x97, 0x14, 0x85, 0x6e, 0xe2, + 0x33, 0xb3, 0x90, 0x2a, 0x59, 0x1d, 0x0d, 0x5f, 0x29, 0x25}; + +guint8 goodix_53xd_config[] = { + 0x70, 0x11, 0x60, 0x71, 0x2c, 0x9d, 0x2c, 0xc9, 0x1c, 0xe5, 0x18, + 0xfd, 0x00, 0xfd, 0x00, 0xfd, 0x03, 0xba, 0x00, 0x01, 0x80, 0xca, + 0x00, 0x08, 0x00, 0x84, 0x00, 0xbe, 0xc3, 0x86, 0x00, 0xb1, 0xb6, + 0x88, 0x00, 0xba, 0xba, 0x8a, 0x00, 0xb3, 0xb3, 0x8c, 0x00, 0xbc, + 0xbc, 0x8e, 0x00, 0xb1, 0xb1, 0x90, 0x00, 0xbb, 0xbb, 0x92, 0x00, + 0xb1, 0xb1, 0x94, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x98, + 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, + 0xd4, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x01, 0x05, 0xd0, 0x00, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x00, 0x72, 0x00, 0x78, 0x56, 0x74, 0x00, 0x34, 0x12, 0x20, + 0x00, 0x10, 0x40, 0x2a, 0x01, 0x02, 0x04, 0x22, 0x00, 0x01, 0x20, + 0x24, 0x00, 0x32, 0x00, 0x80, 0x00, 0x01, 0x00, 0x5c, 0x00, 0x01, + 0x01, 0x56, 0x00, 0x24, 0x20, 0x58, 0x00, 0x01, 0x02, 0x32, 0x00, + 0x04, 0x02, 0x66, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x58, 0x82, + 0x00, 0x7f, 0x08, 0x2a, 0x01, 0x82, 0x07, 0x22, 0x00, 0x01, 0x20, + 0x24, 0x00, 0x14, 0x00, 0x80, 0x00, 0x01, 0x40, 0x5c, 0x00, 0xe7, + 0x00, 0x56, 0x00, 0x06, 0x14, 0x58, 0x00, 0x04, 0x02, 0x32, 0x00, + 0x0c, 0x02, 0x66, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x58, 0x82, + 0x00, 0x80, 0x08, 0x2a, 0x01, 0x08, 0x00, 0x5c, 0x00, 0x01, 0x01, + 0x54, 0x00, 0x00, 0x01, 0x62, 0x00, 0x08, 0x04, 0x64, 0x00, 0x10, + 0x00, 0x66, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x58, 0x2a, 0x01, + 0x08, 0x00, 0x5c, 0x00, 0xdc, 0x00, 0x52, 0x00, 0x08, 0x00, 0x54, + 0x00, 0x00, 0x01, 0x66, 0x00, 0x00, 0x02, 0x7c, 0x00, 0x00, 0x58, + 0x20, 0xc5, 0x1d}; + +static const FpIdEntry id_table[] = { + {.vid = 0x27c6, .pid = 0x538d}, + {.vid = 0, .pid = 0, .driver_data = 0}, +}; + + +static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) ; diff --git a/libfprint/meson.build b/libfprint/meson.build index 626e34123..005f42fce 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -143,6 +143,8 @@ driver_sources = { [ 'drivers/goodixtls/goodix511.c' ], 'goodixtls52xd' : [ 'drivers/goodixtls/goodix52xd.c' ], + 'goodixtls53xd' : + [ 'drivers/goodixtls/goodix53xd.c' ], } helper_sources = { diff --git a/meson.build b/meson.build index b30cced16..ba3a6ca5b 100644 --- a/meson.build +++ b/meson.build @@ -125,6 +125,7 @@ default_drivers = [ 'goodixmoc', 'goodixtls511', 'goodixtls52xd', + 'goodixtls53xd', 'nb1010', # SPI @@ -160,6 +161,7 @@ driver_helper_mapping = { 'elanspi' : [ 'udev' ], 'goodixtls511' : [ 'goodixtls' ], 'goodixtls52xd' : [ 'goodixtls' ], + 'goodixtls53xd' : [ 'goodixtls' ], 'virtual_image' : [ 'virtual' ], 'virtual_device' : [ 'virtual' ], 'virtual_device_storage' : [ 'virtual' ], From 8adc067b379d9d17772b9ffea3bf8b7245619528 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Tue, 26 Oct 2021 11:48:21 +0200 Subject: [PATCH 50/57] Remove unused code and definitions --- libfprint/drivers/goodixtls/goodix52xd.c | 68 ------------------------ libfprint/drivers/goodixtls/goodix52xd.h | 9 +--- 2 files changed, 1 insertion(+), 76 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c index a2276cd94..c336bbf48 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.c +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -546,74 +546,6 @@ static void scan_on_read_img(FpDevice* dev, guint8* data, guint16 len, } } -gboolean -save_image_to_pgm2 (guchar *data, const char *path) -{ - FILE *fd = fopen (path, "w"); - size_t write_size = 7656; - int r; - - if (!fd) - { - g_warning ("could not open '%s' for writing: %d", path, errno); - return FALSE; - } - - r = fprintf (fd, "P2\n%d %d\n255\n", - GOODIX52XD_WIDTH, GOODIX52XD_HEIGHT); - if (r < 0) - { - fclose (fd); - g_critical ("pgm header write failed, error %d", r); - return FALSE; - } - - for (int i = 0; i < write_size; i += 1) { - r = fprintf(fd, "%d\n", data[i]); - } - fclose (fd); - g_debug ("written to '%s'", path); - - return TRUE; -} - -gboolean -save_image_to_pgm (FpImage *img, const char *path) -{ - FILE *fd = fopen (path, "w"); - size_t write_size; - const guchar *data = fp_image_get_data (img, &write_size); - int r; - - if (!fd) - { - g_warning ("could not open '%s' for writing: %d", path, errno); - return FALSE; - } - - r = fprintf (fd, "P5 %d %d 255\n", - fp_image_get_width (img), fp_image_get_height (img)); - if (r < 0) - { - fclose (fd); - g_critical ("pgm header write failed, error %d", r); - return FALSE; - } - - r = fwrite (data, 1, write_size, fd); - if (r < write_size) - { - fclose (fd); - g_critical ("short write (%d)", r); - return FALSE; - } - - fclose (fd); - g_debug ("written to '%s'", path); - - return TRUE; -} - enum scan_empty_img_state { SCAN_EMPTY_NAV0, SCAN_EMPTY_GET_IMG, diff --git a/libfprint/drivers/goodixtls/goodix52xd.h b/libfprint/drivers/goodixtls/goodix52xd.h index 651f00767..d9fbe7531 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.h +++ b/libfprint/drivers/goodixtls/goodix52xd.h @@ -66,11 +66,4 @@ static const FpIdEntry id_table[] = { {.vid = 0, .pid = 0, .driver_data = 0}, }; -static void check_mcu_pov_image(FpDevice* dev, gboolean success, - gpointer user_data, GError* error); - - static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) ; - gboolean -save_image_to_pgm (FpImage *img, const char *path); -gboolean -save_image_to_pgm2 (guchar *data, const char *path); \ No newline at end of file +static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) ; From 3a95f633da49c2323cae5cc299f6b5b4d14131ab Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Wed, 27 Oct 2021 01:50:19 +0200 Subject: [PATCH 51/57] Working OTP Capture --- libfprint/drivers/goodixtls/goodix.c | 2 +- libfprint/drivers/goodixtls/goodix52xd.c | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix.c b/libfprint/drivers/goodixtls/goodix.c index b4aadacbe..e928e762f 100644 --- a/libfprint/drivers/goodixtls/goodix.c +++ b/libfprint/drivers/goodixtls/goodix.c @@ -932,7 +932,7 @@ void goodix_send_tls_successfully_established(FpDevice *dev, void goodix_send_read_otp(FpDevice* dev, GoodixDefaultCallback callback, gpointer user_data) { - GoodixNone payload = {}; + guint8 payload = {0x40, 0x00}; GoodixCallbackInfo* cb_info; if (callback) { diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c index c336bbf48..edb9758ff 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.c +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -79,6 +79,7 @@ enum activate_states { ACTIVATE_CHECK_FW_VER, ACTIVATE_CHECK_PSK, ACTIVATE_RESET, + ACTIVATE_OTP, ACTIVATE_SET_MCU_IDLE, ACTIVATE_SET_MCU_CONFIG, ACTIVATE_NUM_STATES, @@ -253,18 +254,16 @@ static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, fpi_ssm_mark_failed(ssm, err); return; } - /*if (len < 64) { + if (len < 64) { fpi_ssm_mark_failed(ssm, g_error_new(FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID, "OTP is invalid (len: %d)", 64)); return; } - self->otp = malloc(64); - memcpy(self->otp, data, len);*/ FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(dev); - - FpiSsm* otp_ssm = fpi_ssm_new(dev, otp_write_run, 3); - fpi_ssm_start_subsm(ssm, otp_ssm); + self->otp = malloc(64); + memcpy(self->otp, data, len); + fpi_ssm_next_state(ssm); } static void activate_run_state(FpiSsm* ssm, FpDevice* dev) @@ -299,6 +298,10 @@ static void activate_run_state(FpiSsm* ssm, FpDevice* dev) goodix_send_reset(dev, TRUE, 20, check_reset, ssm); break; + case ACTIVATE_OTP: + goodix_send_read_otp(dev, read_otp_callback, ssm); + break; + case ACTIVATE_SET_MCU_IDLE: goodix_send_mcu_switch_to_idle_mode(dev, 20, check_idle, ssm); break; @@ -573,7 +576,7 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) break; case SCAN_EMPTY_GET_IMG: - guint8 payload[] = {0x45, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; + guint8 payload[] = {0x43, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); break; } @@ -586,7 +589,7 @@ static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { - guint8 payload[] = {0x45, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; + guint8 payload[] = {0x43, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; goodix_tls_read_image(dev, &payload, sizeof(payload), scan_on_read_img, ssm); } From b40dc661f0ffa447adeba406790a1b91dd746593 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Wed, 27 Oct 2021 02:02:54 +0200 Subject: [PATCH 52/57] Implement OTP values for finger wait and calibration --- libfprint/drivers/goodixtls/goodix52xd.c | 54 ++++++++++++++++++------ libfprint/drivers/goodixtls/goodix52xd.h | 2 + 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c index edb9758ff..232291845 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.c +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -50,7 +50,7 @@ // extra end #define GOODIX52XD_RAW_FRAME_SIZE \ (GOODIX52XD_HEIGHT * GOODIX52XD_SCAN_WIDTH) / 4 * 6 -#define GOODIX52XD_CAP_FRAMES 10 // Number of frames we capture per swipe +#define GOODIX52XD_CAP_FRAMES 5 // Number of frames we capture per swipe typedef unsigned short Goodix52xdPix; @@ -576,7 +576,9 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) break; case SCAN_EMPTY_GET_IMG: - guint8 payload[] = {0x43, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(img_dev); + guint8 payload[] = {0x43, 0x03, self->otp[26] + 6, 0x00, self->otp[26], 0x00, self->otp[45] + 6, 0x00, self->otp[45], 0x00}; goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); break; } @@ -589,7 +591,9 @@ static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { - guint8 payload[] = {0x43, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00}; + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(img_dev); + guint8 payload[] = {0x43, 0x03, self->otp[26] + 6, 0x00, self->otp[26], 0x00, self->otp[45] + 6, 0x00, self->otp[45], 0x00}; goodix_tls_read_image(dev, &payload, sizeof(payload), scan_on_read_img, ssm); } @@ -600,18 +604,11 @@ const guint8 fdt_switch_state_mode_52xd[] = { 0x92, 0x96, 0x96, 0x8c, 0x8c, 0x01 }; -const guint8 fdt_switch_state_mode1_52xd[] = { - 0x0d, 0x01, 0x27, 0x01, 0x21, 0x01, 0x27, - 0x01, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 -}; - -const guint8 fdt_switch_state_down_52xd[] = { +guint8 fdt_switch_state_down_52xd[] = { 0x9c, 0x01, 0x27, 0x01, 0x21, 0x01, 0x21, 0x01, 0x23, 0x01, 0x8d, 0x8d, 0x86, 0x86, 0x97, 0x97, 0x8f, 0x8f, 0x9b, 0x9b, 0x92, - 0x92, 0x96, 0x96, 0x8c, 0x8c, 0x01, 0x00, + 0x92, 0x96, 0x96, 0x8c, 0x8c, 0x00, 0x00, 0x05, 0x03, 0xa7, 0x00, 0xa1, 0x00, 0xa7, 0x00, 0xa3, 0x00, 0x00 }; @@ -619,6 +616,7 @@ const guint8 fdt_switch_state_down_52xd[] = { static void scan_run_state(FpiSsm* ssm, FpDevice* dev) { FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(img_dev); switch (fpi_ssm_get_cur_state(ssm)) { @@ -629,9 +627,25 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) break; case SCAN_STAGE_SWITCH_TO_FDT_DOWN: + // FDT Down Cali + fdt_switch_state_down_52xd[2] = self->otp[33]; + fdt_switch_state_down_52xd[4] = self->otp[41]; + fdt_switch_state_down_52xd[6] = self->otp[42]; + fdt_switch_state_down_52xd[8] = self->otp[43]; + + // Image Cali + fdt_switch_state_down_52xd[32] = self->otp[26]; + fdt_switch_state_down_52xd[36] = self->otp[45]; + fdt_switch_state_down_52xd[30] = fdt_switch_state_down_52xd[32] + 6; + fdt_switch_state_down_52xd[34] = fdt_switch_state_down_52xd[36] + 6; + + + + fdt_switch_state_down_52xd[26] = 0x00; + goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down_52xd, sizeof(fdt_switch_state_down_52xd), FALSE, NULL, - check_none_cmd, ssm); + receive_fdt_down_ack, ssm); break; case SCAN_STAGE_GET_IMG: fpi_image_device_report_finger_status(img_dev, TRUE); @@ -641,6 +655,20 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) } } +static void receive_fdt_down_ack(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + + fdt_switch_state_down_52xd[26] = 0x01; + goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down_52xd, + sizeof(fdt_switch_state_down_52xd), TRUE, NULL, + check_none_cmd, ssm); +} + static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) { if (error) { diff --git a/libfprint/drivers/goodixtls/goodix52xd.h b/libfprint/drivers/goodixtls/goodix52xd.h index d9fbe7531..2d857afab 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.h +++ b/libfprint/drivers/goodixtls/goodix52xd.h @@ -67,3 +67,5 @@ static const FpIdEntry id_table[] = { }; static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) ; +static void receive_fdt_down_ack(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err); \ No newline at end of file From b14599243e1db09091cf5eb8f9b279d5ad340ff7 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Wed, 27 Oct 2021 02:19:03 +0200 Subject: [PATCH 53/57] Capture 10 images again --- libfprint/drivers/goodixtls/goodix52xd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c index 232291845..4c90a6f61 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.c +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -50,7 +50,7 @@ // extra end #define GOODIX52XD_RAW_FRAME_SIZE \ (GOODIX52XD_HEIGHT * GOODIX52XD_SCAN_WIDTH) / 4 * 6 -#define GOODIX52XD_CAP_FRAMES 5 // Number of frames we capture per swipe +#define GOODIX52XD_CAP_FRAMES 10 // Number of frames we capture per swipe typedef unsigned short Goodix52xdPix; From 8cacb1efd4a8d4526743362171af0cdc080aa215 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Wed, 27 Oct 2021 19:34:11 +0200 Subject: [PATCH 54/57] Added OTP Calibration Mapping to 53xd --- libfprint/drivers/goodixtls/goodix53xd.c | 53 +++++++++++++++++++----- libfprint/drivers/goodixtls/goodix53xd.h | 2 + 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix53xd.c b/libfprint/drivers/goodixtls/goodix53xd.c index 0c5bf665f..4c71310ad 100644 --- a/libfprint/drivers/goodixtls/goodix53xd.c +++ b/libfprint/drivers/goodixtls/goodix53xd.c @@ -79,6 +79,7 @@ enum activate_states { ACTIVATE_CHECK_FW_VER, ACTIVATE_CHECK_PSK, ACTIVATE_RESET, + ACTIVATE_OTP, ACTIVATE_SET_MCU_IDLE, ACTIVATE_SET_MCU_CONFIG, ACTIVATE_NUM_STATES, @@ -253,18 +254,16 @@ static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, fpi_ssm_mark_failed(ssm, err); return; } - /*if (len < 64) { + if (len < 64) { fpi_ssm_mark_failed(ssm, g_error_new(FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID, "OTP is invalid (len: %d)", 64)); return; } - self->otp = malloc(64); - memcpy(self->otp, data, len);*/ FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(dev); - - FpiSsm* otp_ssm = fpi_ssm_new(dev, otp_write_run, 3); - fpi_ssm_start_subsm(ssm, otp_ssm); + self->otp = malloc(64); + memcpy(self->otp, data, len); + fpi_ssm_next_state(ssm); } static void activate_run_state(FpiSsm* ssm, FpDevice* dev) @@ -299,6 +298,10 @@ static void activate_run_state(FpiSsm* ssm, FpDevice* dev) goodix_send_reset(dev, TRUE, 20, check_reset, ssm); break; + case ACTIVATE_OTP: + goodix_send_read_otp(dev, read_otp_callback, ssm); + break; + case ACTIVATE_SET_MCU_IDLE: goodix_send_mcu_switch_to_idle_mode(dev, 20, check_idle, ssm); break; @@ -573,7 +576,9 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) break; case SCAN_EMPTY_GET_IMG: - guint8 payload[] = {0x41, 0x03, 0xa5, 0x00, 0x9f, 0x00, 0xa5, 0x00, 0xa1, 0x00}; + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(img_dev); + guint8 payload[] = {0x41, 0x03, self->otp[26], 0x00, self->otp[26] - 6, 0x00, self->otp[45], 0x00, self->otp[45] - 4, 0x00}; goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); break; } @@ -586,7 +591,9 @@ static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) static void scan_get_img(FpDevice* dev, FpiSsm* ssm) { - guint8 payload[] = {0x41, 0x03, 0xa5, 0x00, 0x9f, 0x00, 0xa5, 0x00, 0xa1, 0x00}; + FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(img_dev); + guint8 payload[] = {0x41, 0x03, self->otp[26], 0x00, self->otp[26] - 6, 0x00, self->otp[45], 0x00, self->otp[45] - 4, 0x00}; goodix_tls_read_image(dev, &payload, sizeof(payload), scan_on_read_img, ssm); } @@ -597,16 +604,17 @@ const guint8 fdt_switch_state_mode_53xd[] = { 0x88, 0x88, 0x00 }; -const guint8 fdt_switch_state_down_53xd[] = { +guint8 fdt_switch_state_down_53xd[] = { 0x8c, 0x01, 0x28, 0x01, 0x22, 0x01, 0x28, 0x01, 0x24, 0x01, 0x91, 0x91, 0x8b, 0x8b, 0x96, 0x96, 0x91, 0x91, 0x98, 0x98, 0x90, 0x90, 0x92, 0x92, - 0x88, 0x88, 0x01 + 0x88, 0x88, 0x00 }; static void scan_run_state(FpiSsm* ssm, FpDevice* dev) { FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); + FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(img_dev); switch (fpi_ssm_get_cur_state(ssm)) { @@ -617,9 +625,17 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) break; case SCAN_STAGE_SWITCH_TO_FDT_DOWN: + // FDT Down Cali + fdt_switch_state_down_53xd[2] = self->otp[33]; + fdt_switch_state_down_53xd[4] = self->otp[41]; + fdt_switch_state_down_53xd[6] = self->otp[42]; + fdt_switch_state_down_53xd[8] = self->otp[43]; + + // First FDT down must not send a reply + fdt_switch_state_down_53xd[26] = 0x00; goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down_53xd, sizeof(fdt_switch_state_down_53xd), FALSE, NULL, - check_none_cmd, ssm); + receive_fdt_down_ack, ssm); break; case SCAN_STAGE_GET_IMG: fpi_image_device_report_finger_status(img_dev, TRUE); @@ -629,6 +645,21 @@ static void scan_run_state(FpiSsm* ssm, FpDevice* dev) } } +static void receive_fdt_down_ack(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err) +{ + if (err) { + fpi_ssm_mark_failed(ssm, err); + return; + } + + // Second FDT down must send a response + fdt_switch_state_down_53xd[26] = 0x01; + goodix_send_mcu_switch_to_fdt_down(dev, (guint8*) fdt_switch_state_down_53xd, + sizeof(fdt_switch_state_down_53xd), TRUE, NULL, + check_none_cmd, ssm); +} + static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) { if (error) { diff --git a/libfprint/drivers/goodixtls/goodix53xd.h b/libfprint/drivers/goodixtls/goodix53xd.h index bcbe5e98e..7178f9933 100644 --- a/libfprint/drivers/goodixtls/goodix53xd.h +++ b/libfprint/drivers/goodixtls/goodix53xd.h @@ -68,3 +68,5 @@ static const FpIdEntry id_table[] = { static void write_sensor_complete(FpDevice *dev, gpointer user_data, GError *error) ; +static void receive_fdt_down_ack(FpDevice* dev, guint8* data, guint16 len, + gpointer ssm, GError* err); \ No newline at end of file From bbee7b667a3397f0b9bb7dce117dc69f3b1641a0 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Tue, 16 Nov 2021 23:57:44 +0100 Subject: [PATCH 55/57] Comment out unecessary code --- libfprint/drivers/goodixtls/goodix52xd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c index 4c90a6f61..cbd8e09f9 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.c +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -229,7 +229,7 @@ enum otp_write_states { static void otp_write_run(FpiSsm* ssm, FpDevice* dev) { - FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(dev); + /*FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(dev); switch (fpi_ssm_get_cur_state(ssm)) { case OTP_WRITE_1: guint8 sensor1[] = {0x0a, 0x02}; @@ -244,7 +244,7 @@ static void otp_write_run(FpiSsm* ssm, FpDevice* dev) ssm); fpi_ssm_next_state(ssm); break; - } + }*/ } static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, From de5990838c2ef8813388a48811fbccc11088475b Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Wed, 17 Nov 2021 00:06:54 +0100 Subject: [PATCH 56/57] Whatever this C error is, I don't enjoy it --- libfprint/drivers/goodixtls/goodix511.c | 3 ++- libfprint/drivers/goodixtls/goodix52xd.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix511.c b/libfprint/drivers/goodixtls/goodix511.c index 7e38b3caf..faf7a912d 100644 --- a/libfprint/drivers/goodixtls/goodix511.c +++ b/libfprint/drivers/goodixtls/goodix511.c @@ -591,11 +591,12 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) goodix_send_nav_0(dev, check_none_cmd, ssm); break; - case SCAN_EMPTY_GET_IMG: + case SCAN_EMPTY_GET_IMG: { GoodixDefault payload = {.unused_flags = 0x01}; goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); break; } + } } static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) diff --git a/libfprint/drivers/goodixtls/goodix52xd.c b/libfprint/drivers/goodixtls/goodix52xd.c index cbd8e09f9..9eb5d70f0 100644 --- a/libfprint/drivers/goodixtls/goodix52xd.c +++ b/libfprint/drivers/goodixtls/goodix52xd.c @@ -575,13 +575,14 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) goodix_send_nav_0(dev, check_none_cmd, ssm); break; - case SCAN_EMPTY_GET_IMG: + case SCAN_EMPTY_GET_IMG: { FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); FpiDeviceGoodixTls52XD* self = FPI_DEVICE_GOODIXTLS52XD(img_dev); guint8 payload[] = {0x43, 0x03, self->otp[26] + 6, 0x00, self->otp[26], 0x00, self->otp[45] + 6, 0x00, self->otp[45], 0x00}; goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); break; } + } } static void scan_empty_img(FpDevice* dev, FpiSsm* ssm) From 80030a2d6fd45e65eb6c1b3ca65a152912637c79 Mon Sep 17 00:00:00 2001 From: Michael Teuscher Date: Wed, 17 Nov 2021 00:10:08 +0100 Subject: [PATCH 57/57] C error --- libfprint/drivers/goodixtls/goodix53xd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libfprint/drivers/goodixtls/goodix53xd.c b/libfprint/drivers/goodixtls/goodix53xd.c index 0affd8e76..42f52b15e 100644 --- a/libfprint/drivers/goodixtls/goodix53xd.c +++ b/libfprint/drivers/goodixtls/goodix53xd.c @@ -229,7 +229,7 @@ enum otp_write_states { static void otp_write_run(FpiSsm* ssm, FpDevice* dev) { - FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(dev); + /*FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(dev); switch (fpi_ssm_get_cur_state(ssm)) { case OTP_WRITE_1: guint8 sensor1[] = {0x0a, 0x02}; @@ -244,7 +244,7 @@ static void otp_write_run(FpiSsm* ssm, FpDevice* dev) ssm); fpi_ssm_next_state(ssm); break; - } + }*/ } static void read_otp_callback(FpDevice* dev, guint8* data, guint16 len, @@ -575,13 +575,14 @@ static void scan_empty_run(FpiSsm* ssm, FpDevice* dev) goodix_send_nav_0(dev, check_none_cmd, ssm); break; - case SCAN_EMPTY_GET_IMG: + case SCAN_EMPTY_GET_IMG: { FpImageDevice* img_dev = FP_IMAGE_DEVICE(dev); FpiDeviceGoodixTls53XD* self = FPI_DEVICE_GOODIXTLS53XD(img_dev); guint8 payload[] = {0x41, 0x03, self->otp[26], 0x00, self->otp[26] - 6, 0x00, self->otp[45], 0x00, self->otp[45] - 4, 0x00}; goodix_tls_read_image(dev, &payload, sizeof(payload), on_scan_empty_img, ssm); break; } + } } static void scan_empty_img(FpDevice* dev, FpiSsm* ssm)