Emergent Design Emergent Design Atom Github

Cooking up Quiche

13 May 2013

Introducing PsiLoc and Qui

We’ve recently been working on PsiLoc, a rather exciting biometrics project with Perception Sensors and Instrumentation. We didn’t write the face recognition code ourselves - we simply selected a third-party library based upon cost, ease of use and performance - but rather addressed the problem of converting some cool components into a fully functional device. The interesting challenge was to make everything just work out of the box without needing configuration and also to make the whole system - including administration and enrollment - work without needing any screens or input devices beyond the prox card reader built into the units. We’re pretty proud of the results, which we named Qui during the development cycle.

An aim for PsiLoc was always to make it useful either as a standalone unit or as a component in a larger system without compromising data security. To achieve the latter we designed Qui to publish interesting events over websockets. Together with a REST service which allows you to request additional information, it’s possible to hook Qui into whatever you like; simply watch for the events you’re interested in (successful verification, for example) and do whatever you like with them. Qui doesn’t allow you to inject data to it’s own store, though: If you want to modify a user or enrol someone you need to physically use PsiLoc with the appropriate control cards; it’s all inherently secured through the same biometrics that you’re using for day-to-day use.

Quiche: an open source Qui cache client

Qui publishes events over a log channel with a fairly simple semicolon delimited format. Rather than just document this, we thought it’d be most useful to systems integrators to provide a reference implementation and a handy API. Quiche is the result - an open source C# API which makes integration easy. The main Quiche readme documents the underlying protocol, so if you’re using a different language you can roll your own solution.

using (var client = new Quiche.Client())
{
    // Tell the client where it's connecting to
    client.Address = "qui.server.ip.address";
    
    // We're not providing a cache so initialise will just set 
    // the connection thread in motion
    client.Initialise();
    
    // Hook in our event handler for connection events (so that 
    // we can respond to disconnection or connection with the 
    // server appropriately)
    client.ConnectionChanged += this.OnConnection;
    
    // Hook in the event handler for log events. We probably 
    // want to write them to file.
    client.LogReceived += this.OnLog;
    
    // Hook in the event handler for status ping events - these 
    // are for keeping track of which terminals are alive
    client.StatusPinged += this.OnStatusPing;
    
    // Tell the client to connect
    client.Connect = true;
    
    while (!this.exit)
    {
        // Do stuff...
    }
}

As well as consuming the published information, Quiche provides an easy way to read and write prox cards using the USB prox device which Perception also provides.

public Connect(string connection)
{
	// Handle card read completion
	this.cardReader.CardRead += (tokenType, pin, units, zones) => {
        Console.WriteLine(
            "Card Read: {0} card with pin {1}. {2} units and {3} zones are whitelisted", 
	        tokenType, pin, units.Count, zones.Count
        );
		this.cardReader.Pause();
	};
	
	// Handle card write completion
	this.cardReader.CardWritten += (success) => {
		Console.WriteLine("Write {0}", success ? "Completed: "Aborted");
		this.cardReader.Pause();
	};
	
	// Handle aborted operations...
	this.cardReader.CancelCardOperation += (writeAborted) => {
		Console.WriteLine("{0} operation aborted", writeAborted ? "Write": "Read");
		this.cardReader.Pause();
	};
	
    // Create a new prox reader
    var device = new PerceptionProx();
    
    // Initialise it with the port it's connecting to, and test 
    // that it seems to be a working connection
    if (device.Initialise(commPort) && device.TestConnection()) 
    {
        // The cardReader is going to take posession of device so we don't need to 
        // worry about disposing it once we've connected
        this.cardReader.Connect(device);
    }
}

// Call this to read a card
public void Read()
{
    this.cardReader.Read();
}

// Call this to write a card
public void Write(TokenType tokenType, uint pin, List<ushort> zones, List<ushort> terminals)
{
    this.cardReader.WriteCard(tokenType, pin, zones, terminals);
}

Again, the data format on the cards is fully documented so if you want to roll your own solution you can.

QuiRing, included in the Quiche project, is an example application showing how to use Quiche to author cards, monitor and log events fired by Qui and maintain a local cache of interesting data. For small sites, QuiRing is probably all you’re going to need. It’s cross-platform, so should run on whatever OS you need it to and, like the rest of Quiche, is completely free to use for whatever you like.

If you have any issues with Quiche, or really need it to do something else, file tickets over on Github. To get hold of a development kit, including a PsiLoc terminal and card reader, or for full systems for deployment contact either Perception or their local distributor.

Credit where it’s due

Quiche is built on some excellent open source software which we heartily recommend:

Qui also uses: