I'm currently trying to interface to an ACS AET62 Fingerprint Reader from C#. The reader comes with an SDK, along with what appear to be extensive example applications. However, the applications contain bugs which the documentation does not help to resolve. I thought I would record the bugs I have found, and how I have resolved them.
ABSEnroll has a ref int parameter which is returned as a pointer to an ABS_BIR structure. This is declared in the provided BSTypes.cs file as containing a header followed by 2560 bytes of data. Unfortunately, this is not correct - it contains a header followed by up to 2560 bytes of data. The actual length of the whole structure (including the header) is contained in the first uint Length member of the structure.
This kind of variable length structure is quite common in C++, but there is no built-in way to marshal it correctly in C#.
The code provided in the SDK just calls Marshal.PtrToStructure on it - this will run off the end of the allocated memory, and assign garbage to the last (should be unused) bytes of the ABS_BIR structure. That's sort of OK in a 32-bit operating system (it is unlikely to try to access memory that doesn't exist), but in a 64-bit one with properly protected memory, it may well throw an exception.
The correct way to marshal the structure is in two parts - first marshal the header part with Marshal.PtrToStructure, then allocate the data byte array to the length therein (first subtracting the length of the header itself), and use Marshal.Copy to copy the remainder.
ppEnrolledTemplate = new BSTypes.ABS_BIR();
BSTypes.ABS_BIR_HEADER hdr = (BSTypes.ABS_BIR_HEADER) Marshal.PtrToStructure(ptr, typeof(BSTypes.ABS_BIR_HEADER));
ppEnrolledTemplate.Header = hdr;
int hdrlen = Marshal.SizeOf(hdr);
int bodylen = (int)(hdr.Length - hdrlen);
ppEnrolledTemplate.Data = new byte[bodylen];
Marshal.Copy(new IntPtr(tset + hdrlen), ppEnrolledTemplate.Data, 0, bodylen);
ABSVerify takes a reference to an IntPtr which is represented in C++ as **ABS_BIR - it is supposed to be an array of pointers to ABS_BIR. The example code provided just passed one ABS_BIR - it used Marshal to allocate a chunk of global memory and marshal the structure into it. The resulting IntPtr was passed as the ref parameter. This is all very fine if you only want to verify a single fingerprint, but if you want to determine which of a list of fingerprints is being scanned (as I did), it is no help at all.
My knowledge of C++ finally allowed me to figure out what was needed. - first, allocate an array of IntPtr (one for each ABS_BIR fingerprint scan you wish to pass). Then allocate memory for each structure into its corresponding IntPtr, and use Marshal to copy the structure into the allocated memory. Finally, pass a reference to the 0'th element of the array.
In actual fact, there is no need to Marshal the ABS_BIR structure during Enroll or Verify - it can be treated as an opaque array of bytes (with the length of the whole thing in the first 4 bytes) - other than the length, there is no other interesting data in the ABS_BIR structure.
Also, during Verify, you can make a single call to allocate enough memory for all the structures you want to pass, and calculate the values of the IntPtrs to pack the data into the single block of memory.
I hope this helps anyone else struggling with this SDK.
Monday, 7 November 2011
Saturday, 19 February 2011
VMWare Workstation on Windows
Having abandoned CentOs as the host for my VMWare VMs, I went back to running Windows XP as the host.
A bit of a pain (two sets of virus detectors, and all the other bloatedness of Windows). That would have been OK, except that most times I started the client, it decided it had only 1 monitor, and rearranged my desktop accordingly. So every morning, the first few minutes would be spent putting things back on the correct monitor. Would you believe that moving a quick launch toolbar from one monitor to another reorders all the icons?
At least my USB 3 drive worked (and aren't they _fast_ !). And my headset.
However, performance was not good, and too many things caused screen updating to stop working. And VM clients had a tendency to jump from one (ATI Hydravision) virtual desktop to another (on the server).
The NTFS filesystem going corrupt, so that one of the 2GB files that made up my hard disk suddenly thought it was 2TB was the last straw.
I finally gave in, and decided to "de-virtualise" my desktop. I took loads of backups, made a BartPE CD, booted it, and repartitioned my disk. Then I restored the backup of my VM client desktop, and rebooted.
Then I was stuck in a boot loop - as soon as the Windows logo appeared, the machine rebooted. Safe mode (even safe mode with command line) did not help. The only way out was a repair install with the latest CD I had (XP64 SP1), followed by a whole day downloading updates and service packs and copies of Internet Explorer.
So I can now advise that virtualisation is not ready to host your desktop on the one machine, and that changing the hardware of your Windows working environment is still a horrible nightmare.
CentOs and VMWare Workstation
I had other problems with my CentOs VMWare WOrkstation host environment. I have a Logitek USB headset, which I use with Skype in my VM client running Windows XP.
However, a while ago the microphone stopped working - all I got from it was a load crackling noise. I tried buying a new headset, but that was the same - it seems to be a reaction between CentOs and VMWare.
Yet another reason to abandon CentOs :-(
CentOs and USB 3.0
I run CentOs 5 as a host operating system for VMWare Workstation, and use a VM client as my main working environment.
I was finding backing up my environment to be a slow and painful process using USB2 disks, or the Gigabit network card.
I read that USB 3.0 was much faster, and that Linux was the first O/S to support it, so I bought a controller card and disk.
Then I found CentOs didn't support it :-(
I was encouraged by the nice people at el-repo to try their experimental kernel for CentOs, and, after a lot of messing about, I managed to get it booted, and accessing the USB 3 disk. However, I couldn't also use their fglrx ATI Radeon driver at the same time (it only works with the stock CentOs kernel). As dual monitor support is vital to me, I gave up, and finally abandoned CentOs.
Thursday, 3 December 2009
U8230 MoDaCo ROM makes ShopSavvy work on Android T-Mobile Pulse
Well, I installed the U8230 MoDaCo ROM, and it sort of worked.
Unfortunately, things (especially the front screen) kept crashing.
However, after advice from the nice MoDaCo people, I did a factory reset...
Unfortunately, things (especially the front screen) kept crashing.
However, after advice from the nice MoDaCo people, I did a factory reset...
- Use the Quick Boot app to go into recovery mode
- Allow the root shell access when the prompt comes up
- Choose the factory reset option
- When the system restarts it will come up with the standard French options - go into Settings/Locale and text/Select locale and choose English.
- I found I had to reboot the phone again to make that setting take properly.
- Now you have to reinstall all your apps (but, if you go to Market, My downloads, they are all listed ready to install). I have installed CoPilot Live (paid for), but it downloaded and installed OK, and re-registered fine.
Because this version of the ROM has moved Google Maps into the data partition (to save space), the factory reset removed it (as it wipes the data partition). So I then had to reinstall the update again. I would advise factory resetting before installing this ROM.
There are some good things about this ROM though:
- ShopSavvy can use the camera like it should (the old version just showed a black screen).
- Google contacts will sync OK (even if you add people to your Favorites).
ShopSavvy doesn't work on Android T-Mobile Pulse
One of the highly recommended applications on Android is ShopSavvy. Apparently this lets you use the phone's camera to scan barcodes of products, and then tells you the best prices to buy them, both locally and on the 'Net.
Sounds good, but doesn't work on my Pulse :-(
However, the excellent Paul at MoDaCo has produced a custom rom based on the French U8230 version of this phone, which fixes the problem. (For those not wishing to root their phone, ShopSavvy have been told by the phone manufacturer that a new ROM image has been supplied to T-Mobile, so just wait patiently!)
So I'm loading it now - for full instructions see http://trumphurst.blogspot.com/2009/12/rooting-android-on-t-mobile-pulse.html - but use http://www.romraid.com/paul/pulse/update-pulse-u8230edition-1.0-core-signed.zip instead of update-pulse-1.3-core-signed.zip.
Sounds good, but doesn't work on my Pulse :-(
However, the excellent Paul at MoDaCo has produced a custom rom based on the French U8230 version of this phone, which fixes the problem. (For those not wishing to root their phone, ShopSavvy have been told by the phone manufacturer that a new ROM image has been supplied to T-Mobile, so just wait patiently!)
So I'm loading it now - for full instructions see http://trumphurst.blogspot.com/2009/12/rooting-android-on-t-mobile-pulse.html - but use http://www.romraid.com/paul/pulse/update-pulse-u8230edition-1.0-core-signed.zip instead of update-pulse-1.3-core-signed.zip.
SSH into my Android T-Mobile Pulse phone
Having installed the MoDaCo Custom ROM into my rooted phone, I then tried to ssh into it. The first thing I needed was the password - the instructions weren't clear, but I eventually found it in Settings/About Phone/Setup Wizard.
I used Putty to SSH into the phone (having got its IP address from my DHCP server logs) as root (using port 2222), and it worked. Now I wanted to use my public key, so I wouldn't be asked for the password again. Instructions were a bit fragmented, and I had a few false starts, but this is what I ended up doing:
I used Putty to SSH into the phone (having got its IP address from my DHCP server logs) as root (using port 2222), and it worked. Now I wanted to use my public key, so I wouldn't be asked for the password again. Instructions were a bit fragmented, and I had a few false starts, but this is what I ended up doing:
- cd /data/dropbear
- mkdir .ssh
- chmod 700 .ssh
- cd .ssh
- echo 'my public key' >authorized_keys
- chmod 644 authorized_keys
- cd ..
- mount -o rw,remount -t yaffs2 /dev/block/mtdblock1 /system
- edit /system/bin/dropbear.sh to add
-R /data/dropbear/.ssh/authorized_keys
to the end of the command line. - mount -o ro,remount -t yaffs2 /dev/block/mtdblock1 /system
- reboot the phone (type "reboot" at the command line, or use the Quick Boot app on the phone).
The mount commands switch the filesystem from read-only (its usual state) to read-write and back again.
Brilliant - I now have password-free root access to my phone using ssh from my PC (which has a real keyboard). Some experimentation shows I have most of the commonly-used Linux commands available to me.
Subscribe to:
Posts (Atom)