Hi,

I just spent some time sniffing what UPEK's new libbsapi is doing, and produced a libusb-1.0 app to do the same. It works - it captures image data. I'm not totally clear on the format, but the output file looks quite nice when plotted as 8 bit greyscale with a width of 2306 pixels (although the fingerprint is repeated).

This is for hackers only, and probably requires you to run bsapi's FirstStep program first. Just wanted to push this out there as I'm pretty busy at the moment, it might be a while before I get back on this.

Daniel
/*
 * reverse engineering 0x147e:0x2016 fingerprint reader
 * Copyright (C) 2007-2008 Daniel Drake <[EMAIL PROTECTED]>
 * 
 * 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 <libusb.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

static int capturing = 500;
static libusb_device_handle *handle;
static FILE *fd;
static void ctrl_read8(uint16_t index)
{
        unsigned char buf[8];
        int r;

        r = libusb_control_transfer(handle, 0xc0, 0x0c, 0, index, buf, 8, 5000);
        printf("read8 %x = %d: %02x %02x %02x %02x %02x %02x %02x %02x\n", 
index, r,
                buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
}

static void write_reg(uint16_t reg, uint8_t val)
{
        int r;
        r = libusb_control_transfer(handle, 0x40, 0x0c, 0, reg, &val, 1, 5000);
        printf("write reg %x = %d\n", reg, r);
}

static void bulkin(int len)
{
        int actual;
        unsigned char buf[len];
        int r = libusb_bulk_transfer(handle, 0x81, buf, len, &actual, 5000);
        printf("bulkin %d = %d,%d: %02x %02x %02x %02x %02x %02x %02x %02x 
...\n",
                len, actual, r,
                buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
}

static void bulkcb(struct libusb_transfer *transfer)
{
        unsigned char *buf = transfer->buffer;
        printf("cb stat=%d,%d: %02x %02x %02x %02x %02x %02x %02x %02x\n",
                transfer->status, transfer->actual_length,
                buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
        int i;

        for (i = 0; i < 4096; i += 64)
                fwrite(buf + i + 2, 1, 62, fd);
        capturing--;
        libusb_submit_transfer(transfer);
}

static void onebulk(void)
{
        struct libusb_transfer *transfer = libusb_alloc_transfer(0);
        unsigned char *buf = malloc(4096);
        libusb_fill_bulk_transfer(transfer, handle, 0x81, buf, 4096, bulkcb,
                NULL, 5000);
        libusb_submit_transfer(transfer);
}

static void startbulk(void)
{
        int i;
        for (i = 0; i < 24; i++)
                onebulk();
}

int main(void)
{
        int r;

        libusb_init(NULL);
        handle = libusb_open_device_with_vid_pid(NULL, 0x147e, 0x2016);
        if (!handle)
                return 2;

        /* ABSOpen */
        libusb_set_configuration(handle, 1);
        ctrl_read8(0x17);
        write_reg(0x49, 0x00);
        write_reg(0x3e, 0x83);
        write_reg(0x3e, 0x4f);
        write_reg(0x3e, 0x0f);
        write_reg(0x3e, 0xbf);
        write_reg(0x3e, 0x43);
        write_reg(0x3e, 0x35);
        write_reg(0x3e, 0x1c);
        write_reg(0x3e, 0xae);
        write_reg(0x44, 0x01);
        write_reg(0x43, 0x06);
        write_reg(0x43, 0x05);
        ctrl_read8(0x45);
        write_reg(0x43, 0x04);
        write_reg(0x44, 0);
        write_reg(0x44, 0x9d);
        write_reg(0x40, 0x1f);
        write_reg(0x41, 0xb8);
        write_reg(0x42, 0);
        write_reg(0x43, 0x03);
        ctrl_read8(0x45);
        bulkin(64);

        write_reg(0x44, 0);
        write_reg(0x44, 0x9d);
        write_reg(0x40, 0x03);
        write_reg(0x43, 0x03);
        ctrl_read8(0x45);
        bulkin(64);

        write_reg(0x44, 0x00);
        write_reg(0x44, 0x9d);
        write_reg(0x40, 0xff);
        write_reg(0x41, 0xc0);
        write_reg(0x43, 0x03);
        ctrl_read8(0x45);
        ctrl_read8(0x45);
        bulkin(512);

        write_reg(0x44, 0x00);
        write_reg(0x44, 0x9d);
        write_reg(0x41, 0x40);
        write_reg(0x42, 0x03);
        write_reg(0x43, 0x03);
        ctrl_read8(0x45);
        ctrl_read8(0x45);
        bulkin(512);

        write_reg(0x44, 0x00);
        write_reg(0x44, 0x9d);
        write_reg(0x42, 0x05);
        write_reg(0x43, 0x03);
        ctrl_read8(0x45);
        ctrl_read8(0x45);
        bulkin(512);

        write_reg(0x44, 0);
        write_reg(0x44, 0x9d);
        write_reg(0x42, 0x07);
        write_reg(0x43, 0x03);
        ctrl_read8(0x45);
        ctrl_read8(0x45);
        bulkin(512);

        write_reg(0x44, 0);
        ctrl_read8(0x18);
        ctrl_read8(0xb);
        write_reg(0xb, 0);
        ctrl_read8(0x9);
        write_reg(0x9, 0x27);
        ctrl_read8(0x13);
        write_reg(0x13, 0);
        write_reg(0x4, 0);
        write_reg(0x5, 0);

        /* ABSEnroll */
        printf("scan finger now\n");
        sleep(1);
        ctrl_read8(0x17);
        ctrl_read8(0xa);
        write_reg(0xa, 0);
        ctrl_read8(0xa);
        write_reg(0xa, 0);
        ctrl_read8(0x9);
        write_reg(0x09, 0x20);
        ctrl_read8(0x3);
        write_reg(0x3, 0x3b);
        ctrl_read8(0x0);
        write_reg(0x0, 0x67);
        ctrl_read8(0);
        write_reg(0, 0x67);
        ctrl_read8(0x1);
        write_reg(1, 0xc6);
        ctrl_read8(1);
        write_reg(1, 0xc6);
        write_reg(0xc, 0x13);
        write_reg(0xd, 0x0d);
        write_reg(0xe, 0x0e);
        write_reg(0xf, 0xd);
        ctrl_read8(0xb);
        write_reg(0xb, 0);
        ctrl_read8(0x13);
        write_reg(0x13, 0x45);
        ctrl_read8(0x13);
        write_reg(0x13, 0x45);
        ctrl_read8(0x30);
        write_reg(0x30, 0xe0);
        ctrl_read8(0x13);
        write_reg(0x13, 0x55);
        ctrl_read8(0x12);
        write_reg(0x12, 0x01);
        ctrl_read8(0x20);
        write_reg(0x20, 0x01);
        ctrl_read8(0x9);
        write_reg(0x9, 0x20);
        ctrl_read8(0xa);
        write_reg(0xa, 0);
        ctrl_read8(0x30);
        write_reg(0x30, 0xe0);
        ctrl_read8(0x20);
        write_reg(0x20, 0x01);
        ctrl_read8(0x07);
        write_reg(0x07, 0x10);
        ctrl_read8(0x08);
        write_reg(0x08, 0x00);
        write_reg(0x10, 0x00);
        ctrl_read8(0x12);
        write_reg(0x12, 0x01);
        write_reg(0x11, 0xbf);
        ctrl_read8(0x12);
        write_reg(0x12, 0x01);
        ctrl_read8(0x7);
        write_reg(0x17, 0x10);
        ctrl_read8(0x7);
        write_reg(0x17, 0x10);
        write_reg(0x04, 0);
        write_reg(0x5, 0);
        ctrl_read8(0x9);
        ctrl_read8(0xb);
        ctrl_read8(0x13);
        ctrl_read8(0x15);
        ctrl_read8(0x30);
        ctrl_read8(0xb);
        write_reg(0xb, 0x00);

        startbulk();

        write_reg(0x09, 0x28);
        write_reg(0x13, 0x55);
        write_reg(0x0b, 0x80);

        fd = fopen("data.out", "w");
        while (capturing)
                libusb_handle_events(NULL);

        fclose(fd);
        return 0;
}
_______________________________________________
fprint mailing list
[email protected]
http://lists.reactivated.net/mailman/listinfo/fprint

Reply via email to