Bug in der API entdeckt

Nun bin ich doch tatsächlich auf einen Bug in der JavaSDK und den darin enthaltenen nativen Bibilotheken gestoßen.

Bei der Arbeit an der Listener Komponente des Servers kann ich über die JDK eine Listener Instanz erstellen, diese macht einen TCP IP Port auf dem Server auf und wartet auf Notify Requests mit dem RFID Leser.

Den Listener kann man öffnen, allerdings nur mit Plaintext Kommun ikation. Soabld man die Verbindung mit dem Key verschlüsselt bekommt man eine Exception.

Der Support der FEIG ELEKTRONIK GmbH war aber gleich dabei den Fehler zu suchen. War wohl nicht ganz einfach, aber hey – gestern war der Fix für Windows im Postfach (Neue JAR und neue DLLs) und heute kam der Fix für den Raspberry.

Und was soll ich sagen: „ES FUNKTIONERT“.

Was leider noch offen ist, ist ein sauberer Deamonize modus. Der Listener wird als Asynchroner Task im Hintergrund geladen. Und kommt nach Initialisierung im Hauptprogramm wieder an. Das beendet sich dann auch sauber.
Um das Hauptprogramm offen zu halten habe ich eine while(true) schleife mit nem sleep eingebaut. Finde ich etwas unschön aber immerhin kann ich mir die Notifikationen ansehen und die Tabelle mit den Daten auslesen.

PI USV ist an Bord

Heute kam die PI USV+ an.

Aufgesteckt, eingesteckt und … alles blieb dunkel.

Ja – ich weis – Doku lesen hilft. Es gibt nen Ein/Aus Schalter an dem Ding (den versuch ich morgen).

Aber ich hab mir auch so helfen können. Einfach die Stromversorgung beim PI direkt rein und booten. Das funktionierte (klar, warum auch nicht).

Nach dem Einrichten und starten des Dienstes passierte dann etwas unerwartetes. Der Raspberry is runtergefahren. OK – also neu booten.

Ich kam bis zum Login, da war er auch schon wieder unten. Arrrrrgh

*mitflacherhandaufstirnklatsch*

Klar, is ja auch kein Strom an der USV.

Habe dann beschlossen doch mal früh ins Bett zu gehen. Und es morgen mal mit dem zwischenzeitlich in der Doku entdeckten Schalter zu versuchen.

*lol*

Das PI USV+ Dilemma

Wie ich schon berichtet habe, spendiere ich dem Server (Raspberry B+) eine USV um diverse Filesystem crashs zu vermeiden. Ist ja wohl ein bekanntes Problem.

Hier habe ich mich für die PI USV+ entschieden, die von der Firma CW2. GmbH & Co. KG aus Stuttgart angeboten wird.

Am 08.06.2015 habe ich gleich 2 davon bestellt. Die Auslieferung war (gemäß Homepage) für den 30.06.2015 geplant. Das Geld habe ich dann online am 09.06.2015 angewiesen und warte seitdem auf Lieferung oder Feedback.

Am 23.06.2015 habe ich dann eine der beiden PI USVs wieder storniert, da ich nur noch eine davon einsetzen kann und hatte gefragt ob sie mir bitte das Geld entsprechend zurück überweisen könnten. Leider habe ich hier weder den Betrag zurück überwiesen bekommen noch kam bei mir eine Antwort an. Selbst nicht als ich bei CW2 am 26.6. nochmals angefragt hatte diesbezüglich.

Im firmeneigenen Kundenforum gibt es auch nur Anfragen von anderen Bestellern ohne eine Antwort von CW2. Habe ich nach dem Auftritt auf Facebook gesucht und gefunden.
Und hier auch gleich mal einen Kommentar auf deren Pinnwand hinterlassen.
Hier ist die Reichweite vermutlich größer als in irgend einem Forum (bei dem man sich vorher anmelden und freigeschaltet werden muss).

Hier gab es dann tatsächlich auch folgende Antwort:

Guten Morgen Zusammen, Ich kann gut verstehen dass hier große Frustration herrscht – ihr seit nicht alleine, wir haben mit unzähligen Verschiebungen zu Kämpfen gehabt. Bis zuletzt wurde uns von unserem Lieferanten kein endgültiger Lieferzeitpunkt genannt. Aus diesem Grund haben wir noch nicht an alle Kunden kommuniziert. Ein weiteres nicht eingehaltenes Liferversprechen konnten wir uns nicht leisten. Gestern haben wir nun endlich die Lieferfreigabe erhalten und können deswegen heute die versprochenen Bestätigungen verschicken. Viele Grüße, PiUSV+ Team

Zwisschenzeitlich steht auf der Homepage statt dem 30.06.2015 als voraussichtliches Lieferdatum nur noch: „Auslieferung nach Lagerverfügbarkeit„.

Da ich mit der Entwicklung des Zugangs-Kontroll-Systems noch (leider) ein Weilchen vom goLive weg bin, warte ich eben auf Antwort und werde evtl. nochmals eine Mail verfassen damit nicht in lauter Hektik (HeadlessChickenMode) doch 2 USVs zu mir geschickt werden.

Ich will mit meinem eintrag hier im Blog die Firma CW2 nicht schlecht machen, die Produkte kenn ich ja noch nicht 🙂
Aber die Kommunikation zu den Kunden ist nicht gut geregelt. Hier könnte der Vertrieb sich evtl. besser aufstellen. Vor allem einem Endkunden entgegen.

So, ich mach jetzt Mittagessen für meinen Kleinen, der kommt demnächst aus dem Kindi.

Der Listener, das unbekannte Wesen und andere Fortschritte

Zum Stand der Dinge.

Hier seht Ihr den aktuellen Fortschritt des Projekts.

2015-07-17-Architektur-SchaubildFür das Logging von Informationen habe ich mich für den defacto Standard Log4J entschieden.  Bislang gebe ich nur auf STD OUT statt in eine Datei, aber das ist (soweit ich gesehen habe) nur noch eine Konfigurationssache.

Den Bereich der extern ausgelagerten Konfiguration (Kasten: „Config“) habe ich ebenfalls gelöst. Ursprünglich hatte ich mir zunächst die Crunchify Lösung aus dem Internet angesehen mich dann aber doch nach einigem hin und her für eine eigene Lösung entschieden. Diese habe ich in dem Artikel Konfigurationsdateien beschrieben.

Mit der OBID Listener Komponente habe ich nun angefangen mit der Entwicklung. Leider stieß ich relativ schnell auf komische Efffekte. Hier habe ich auch schon eine Supportanfrage gestellt bin aber guter Dinge das mir da die FEIG ELECTRONIC GmbH auf die Sprünge helfen kann.

Konfigurationsdateien

„Hardcoded configuration“ ist schlechter Stil, daher habe ich mir vorgenommen meine Parameter extern in einer Konfigurationsdatei zu halten und eine kleine Helferklasse im Java zu schreiben die mir die Daten einliest.

die nutzung ist denkbar einfach, nach dem Import der Klasse kann man mit 2 einfachen Kommandos die Konfig Datei laden und einen Parameter einlesen.

Beispiel:

import de.oberdorf_itc.textproc.ConfigFile;
[..]
ConfigFile prop = new ConfigFile();
[..]
// read in the configuration file
prop.getProperties("/home/cybcon/etc/my_config.properties");
// get the parameter
String value = prop.getValue("myAttribute");
[..]

die Konfigurationsdatei könnte wie folgt aussehen:

myAttribute=This is the attributes value

Hier noch der Quellcode der Klasse „ConfigFile“:

package de.oberdorf_itc.textproc;

/**
 * Import Java libraries
 */
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.File;
import java.util.Properties;
import java.io.FileInputStream;

/**
 *
 * This java class can be used to load configuration files and read
 * the values.
 *
 * @author Michael Oberdorf IT-Consulting
 * @version 0.100
 *
 */
public class ConfigFile {
    static Properties prop = new Properties();

    /**
     * Method to load a configuration file
     *
     * @param configFile (String)
     * @return Properties
     * @throws IOException
     *
     */
     public Properties getProperties(String configFile) throws IOException {
         // Do some error handling
         if (configFile == null) { throw new IOException("File not given."); }
         File FH = new File(configFile);
         if(!FH.exists() || !FH.isFile()) { throw new FileNotFoundException("File not found exception for: " + configFile); }
         else { if (!FH.canRead()) { throw new IOException("No Permission to read file: " + configFile); } }
         // Cleanup FileHandle
         FH = null;

         // get the input stream from file contents
         FileInputStream inputStream = new FileInputStream(configFile);
         prop.load(inputStream);
         inputStream.close();

         // return properties
         return prop;
     }

     /**
      * Method to read an attributes value from the configuration file
      *
      * @param attribute (String)
      * @return String
      * @throws IOException
      *
      */
     public String getValue(String attribute) throws IOException {
         if (attribute == null) { throw new IOException("No attribute given"); }
         return prop.getProperty(attribute);
         }
}

 

 

ACS Architektur

Hier mal ein grobes Architektur Schaubild des geplanten Zugangskontrollsystems.

2015-07-12_ACS_architekturDie grauen Flächen symbolisieren die Hardware, bis auf die Firewall zwischen RFID Leser und Server ist diese bereits im Haus.

Grüne Flächen symbolisieren Funktionen/Abläufe die bereits implementiert wurden.

Gelbe Flächen symbolisieren Funktionen/Abläufe an denen ich gerade arbeite.

Weiße Flächen sind Funktionen/Abläufe die zwar vorgesehen sind, aber noch nicht näher betrachtet wurden.

Die Türe mit dem PiFace Digital 2 öffnen

Meine Recherche war erfolgreich und ich konnte eine kleine Java Klasse erstellen mit der ich den OpenCollector Ausgang (OUT PIN 0) für 500 Millisekunden öffnen (also auf GND ziehen) kann.

Ursprünglich wollte ich mit der Klasse com.pi4j.device.piface.PiFace arbeiten, leider kommt aber Java nach Ausführung nicht wieder zurück.

Ein strace hat ergeben, dass Java auf die Beendigung eines Prozesses wartet. Die angegebene PID im strace war aber nicht mehr im system vorhanden, damit würde die Classe sich wohl nicht wieder beenden. Daher bin ich umgestiegen auf die etwas weiter unten liegende com.pi4j.io.gpio Klassen.

Und hier das Ergebnis:

// Importing Libraries
import com.pi4j.gpio.extension.piface.PiFaceGpioProvider;
import com.pi4j.gpio.extension.piface.PiFacePin;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.spi.SpiChannel;
import java.io.IOException;

/**
 * 
 * @author Michael Oberdorf
 * @version 0.100
 * Description:
 *   PiFaceOut is the class to control the PiFace Digital 2 Output Ports
 *   The Class uses the Pi4J GPIO interface instead of the device.piface class because
 *   the finalizing is defect there.
 *   The GpioController can be shutdown 
 *
 */
public class PiFaceOut {
    public static void main(String args[]) throws InterruptedException, IOException {
        // create gpio controller
        final GpioController gpio = GpioFactory.getInstance();

        // Trigger the Out PIN 00 for 500 milliseconds to open the entrance door
        openDoor(gpio, 500);

        // shut down the interface to clean up native heap from WiringPi
        gpio.shutdown();
    }
    
    /**
     * 
     * private method to trigger the digital output pin 0 to open the entrance door
     * @param gpio (GpioController)
     * @param time (int)
     * @throws IOException
     * @throws InterruptedException
     *
     */
    private static void openDoor(GpioController gpio, int time) throws IOException, InterruptedException {
        // create custom PiFace GPIO provider
        final PiFaceGpioProvider gpioProvider = new PiFaceGpioProvider(PiFaceGpioProvider.DEFAULT_ADDRESS, SpiChannel.CS0);

        // provision gpio output pins and make sure they are all LOW at startup
        GpioPinDigitalOutput myOutputs[] = {
                gpio.provisionDigitalOutputPin(gpioProvider, PiFacePin.OUTPUT_00)
        };

        // pull digital out pin to GND (OpenCollector)
        gpio.setState(true, myOutputs);
        // sleep for a while
        Thread.sleep(time);
        // close the digital out pin
        gpio.setState(false, myOutputs); 
    }
}

Raspberry PI B+

Der neue (alte) Raspberry PI B+ ist nun da und für den Anderen habe ich auch schon einen Abnehmer gefunden.
Das PIFace Digital 2 habe ich dieses mal gleich aufgesteckt, von der PI USV habe ich leider noch nichts gehört.
Das Raspbian Image ist ja das selbe, daher konnte ich ohne Downloads gleich wieder starten den Server zu konfigurieren.
Die Libraries der Feig GmbH waren auch schnell in /usr/lib  untergebracht inklusive der Symlinks. Der erste Test war auch erfolgreich. Die Libraries liesen sich mit Java initialisieren.
Apropos Java, hier muss ich gleich noch schauen ob es da auch was für das PiFace gibt.
URLs die ich zu dem Thema gefunden habe:
Das klingt schon mal interessant und muss ich mir demnächst mal noch näher ansehen.

Neue Serverplatform

Nachdem ich den Raspberry PI 2 B nicht mit den Libs der Firma FEIG verheiraten konnte, hab ich meinen Raspberry PI B ausprobiert, und es hat alles auf anhieb funktioniert. Was mich nun zu dem Entschluß gebracht hat den PI 2 aufzugeben.

Um die restlicher Peripherie behalten zu können, habe ich nun einen Raspberry PI B+ bestellt. Damit wird auch die bestellte USV (auf die warte ich noch immer) und das PiFace Digital 2 arbeiten (so hoffe ich zumindest).

Vieleicht habe ich sogar Glück und das Hutschienengehäuße passt zum B+. Jedenfalls gibt es im Netz genügend Gehäuse die bei beiden funktionieren.

Der Firma FEIG habe ich jedoch positives Feedback gegeben und warte nun auf die Rechnung damit der Leser endlich mein Eigen wird 🙂

Auf der Suche nach dem richtigen Reader

Nachdem ich mich nun auf folgende Dinge festgelegt habe:

  • Verbindung von Server zum Reader via Ethernet
  • Raspberry PI 2 als Server

Bin ich auf die Suche gegangen nach einem RFID Kartenleser den ich im Außenbereich anbringen kann.

In dem Fachgebiet ist die Auswahl wirklich schwer. Zuletzt hatte ich Kontakt zur Firma SALTO Systems AG und der Firma FEIG ELECTRONIC GmbH.

SALTO hatte sich auf meine erste Anfrage gar nicht gemeldet, die Firma Feig dagegen schon.

Ich muss schon sagen, ich bin seit sicher 6 Wochen mit der Firma Feig in sehr regem Kontakt.

Der Support der Firma Feig ist vorbildlich. Kaum vorstellbar das ich die dauernd mit irgendwelchen Fragen nerve, die antworten sogar mit sehr hilfreichen Informationen obwohl ich wirklich ein Miniprojekt am Laufen habe.

Ich bin hoch zufrieden mit der FEIG ELECTRONIC GmbH und bin bestrebt alles zu tun um hier bleiben zu können.

Nach einigen Fragemails und hin und her habe ich mich für den Feig OBID RFID Leser CPR50.10-E  entschieden. dieser unterstützt den Online Modus und die Ethernet Verbindung.

Zudem gibt es die Möglichkeit diverse SDKs frei für die Software Entwicklung zu dem Leser dazu zu bekommen. Da ich von NXP noch immer keine Antwort habe, hoffe ich mit den SDKs um die RFID Kartenbefehle ein wenig herum zu kommen.

Leider konnte mir die Firma Feig nicht zusichern das der Reader mit dem Raspberry PI 2 läuft, der PI (1) ist wohl getestet.
Die Firma bietete mir an den Leser 6 Wochen für Tests kostenlos zur Verfügung zu stellen was ich gerne annahm. Der Leser war 2 Tage später im Haus (echt fix).

Dazu bekam ich noch Zugang zum downloadbereich auf dem die SDKs liegen.

Ich muss sagen, der Leser und die SDKs sind wirklich gut beschrieben und es gibt auch Tutorials zu jedem SDK. Angeboten wird Linux (C++), .NET und Java als SDK.

Da ich mit den enryption Ciphers eh schon mit Java begonnen hatte, habe ich nun angefangen hier das Java SDK zu verwenden.
Die Kommunikation mit dem Reader ist proprietär, man muss also (je nach OS) die entsprechenden Libraries installieren. Nach einigen Startschwierigkeiten habe ich es dann doch unter windows mit Eclipse zum Laufen gebracht.
Nach ein paar Seiten Tutorial hatte ich die Verbindung zum Leser via Ethernet hergestellt.

Zeit das ganze auf den Raspberry PI 2 zu transportieren um die generelle Funktion zu testen. die properitären Libraries lassen sich schnell installieren (.so files in /usr/lib kopieren und ein paar Symlinks anlegen).
Die Größte Schwierigkeit ist eigentlich die passenden Libs für den Prozessor zu finden (armv7-a_vfpv3_hard).
Das Java Programm hab ich via Eclypse in ein JAR gepackt und auf den Raspberry transportiert.

Der Connection Test zum RFID Leser schlug leider bislang fehl. Java sagt mir dass es die libfeusb.so nicht finden kann.
Um den Installationsprozess auf Linux zu prüfen hab ich die passenden Libs für Ubuntu herausgesucht und installiert. Hier hat der Verbindungstest auf anhieb funktioniert.
Diverse Traces (strace) zeigten mir dass Java die libfeusb.so findet und öffnet. Wenn ich den strace mit ubuntu vergleiche, bekomme ich nach der Öffung der libusbfe.so ein Zugriff auf die libusb.so.

Die Feig usb library basiert wohl auf die recht alte libusb 1.0.12.
Diese habe ich von Sourceforge geladen und auf dem Raspberry compilliert und installiert. Leider ohne Erfolg. Ich werde mich die Tage wohl wieder mal an den Support wenden müssen, wobei ich hier langsam schwarz sehe da die den Raspberry PI 2 nicht offiziell unterstützen.

Da der Support der FEIG ELECTRONIC GmbH aber so prima ist, werde ich mich wohl auf die Suche nach einer anderen Serverplatform machen müssen.
Den RFID Leser habe ich jetzt noch 20 Tage für Tests zur Verfügung.

Im Zweifel werde ich Ihn kaufen – das Ding ist nämlich richtig gut.

Server Platform und generelle Infrastruktur

Also, nachdem der Kartentyp klar war, sind 3 Dinge zu klären

  1. ein passender RFID Leser der im Außenbereich einzusetzen ist
  2. das Protokoll bzw. der Anschluß mit dem ich mit dem Leser kommunizieren kann. Zur Auswahl stehen Serial, USB, Bluetooth und Ethernet.
  3. Die Server Platform

Alle 3 Dinge müssen passen und gut zusammenspielen.

Was das Protokoll angeht, Bluetooth fand ich zu unsicher, USB hat Probleme bei langen Kabellängen. Also bleibt Serial und Ethernet.
Da die Türe leider früher kam als erwartet, hatte ich weder Serverplatform noch RFID Leser gewählt, daher habe ich mich mich Ethernet entschieden.

Zum einen erschien es mir am flexibelsten, denn im Ernstfall kann ich auch ein Adernpaar für eine Serielle Verbindung zweckentfremden, zum anderen hatte ich noch genug Ethernet Kabel zu Hause.

Um mal einen Anfang zu finden habe ich mich nun für einen Raspberry entschieden. Der is ja auch so hip derzeit.

Nur wo betreibe ich den? Also am besten ist es den doch gleich im Sicherungskasten unterzubringen.

Und ich habe tatsächlich ein Hutschienen Gehäuse gefunden.

Die Serverplatform ist nun ein Hutschienengehäuse, ein Raspbery PI2 und ein Hutschienen Traffo. Das kam alles schnell an und ich konnte den auch gleich in Betrieb nehmen (mal mit Handy Ladenetzteil auf meinem Schreibtisch),

2 Dinge waren noch zusätzlich zu klären:

  1. Was machen bei einem Stromausfall
  2. Wie steuere ich die Türe an

Für den ersten Punkt habe ich mich für die PI USV+ von CW2.com entschienden, auf die Auslieferung warte ich derzeit.

Für den zweiten Punkt gäbe es entweder eine Billige Lösung in der ich mich in Elektronik einlernen muss oder eine vorgefertigte Lösung. Ich habe mich für letzteres entschieden, etwas gegoogelt und dann das PiFace Digital 2 Borad gekauft das ich schon zu Hause liegen habe. Das Board bietet sowohl 2 Relais (für die man zusätzlich 5V spannung benötigt) als auch diverse digitale Ausgänge.

Nach einigen Mails mit meinem Schwager und der Messung der Kontakte an der Haustüre (4V, 3mA) versuche ich wohl zunächst die digitalen Open Collector Ausgänge zu nutzen. Sollte theoretisch funktionieren wenn ich den positiven Draht auf den digitalen Ausgang hänge und den negativen auf GND. Nun, mal abwarten ob ich mir damit das Board zerschieße oder ich richtig überlegt habe.

 

MIFARE DESFire EV1 via pcsc-perl

Der RFID Chip machte und macht mir noch immer einige Sorgen.

Die Kommunikation erfolgt via sogenannter APDU Kommandos. Das sind 8 byte HEX Strings. [2]
Es gibt wohl nach ISO Standard irgendwelche standard Befehle und es gibt zusätzlich einen DESFire EV1 proprietären Befehlssatz.

Die ISO Befehle sind leider nur rudimentär beschrieben. [2] Jedenfalls habe ich nichts adequates gefunden. Schlimmer noch, die DESFire EV1 Befehle sind gar nicht öffentlich zu bekommen.

Es soll eine Dokumentation von NXP geben die sich „MIFARE DESFire – Implementation hints and examples,document number: 094532″ nennt. In diversen Foren ist davon die Rede dass man die nur nach Unterzeichnung einer NDA bekommt.
Um irgendwie weiter zu kommen habe ich nun einen Account bei NXP.com erstellt und am 1.6. eine Anfrage beim Support erstellt (diese ist Stand heute noch nicht beantwortet worden). Wir harren also der Dinge.

Nichts desto trotz ist es mir nach einiger Recherche gelungen die Basisdaten auszulesen aus einer nicht Verschlüsselten blanko RFID Karte. Also welche Grundlegende Konfiguration diese hat, die UID und ein paar Infos zum Betriebssystem und der Hardware. Hier ein Beispiel (der Quellcode ist NICHT vollständig, es sind nur ein paar Ausschnitte des gesammten Programms):

[..]
# PC/SC Handling
use Chipcard::PCSC;                # to connect to card reader
use Chipcard::PCSC::Card;          # to read smart card
[..]
#---------------------------------------------------------------------#
# sendAPDU
# description: send APDU command and receive data
# input: object (hCard), string (APDU comand)
# return: string (APDU response)
#---------------------------------------------------------------------#
sub sendAPDU
  {
  my $card = shift;
  my $APDU_in = shift;

  my $SendData = Chipcard::PCSC::ascii_to_array($APDU_in);
  my $RecvData = $card->Transmit($SendData);
  if ($RecvData)
    {
    my $APDU_out = Chipcard::PCSC::array_to_ascii($RecvData);
    return ($APDU_out);
    }
  else
    {
    return(undef);
    }
  }
#---------------------------------------------------------------------#
# sendAPDUwithSW
# description: send APDU command and receive data and status word
# input: object (hCard), string (APDU comand)
# return: string (APDU response), string (APDU status word)
#---------------------------------------------------------------------#
sub sendAPDUwithSW
  {
  my $card = shift;
  my $APDU_in = shift;

  my $SendData = Chipcard::PCSC::ascii_to_array($APDU_in);
  my $RecvData = $card->Transmit($SendData);
  my $sw_r = pop(@{$RecvData});
  my $sw_l = pop(@{$RecvData});
  my $sw = [$sw_l, $sw_r];

  my $APDU_out = Chipcard::PCSC::array_to_ascii($RecvData);
  my $SW = Chipcard::PCSC::array_to_ascii($sw);

  return ($APDU_out, $SW);
  }
#---------------------------------------------------------------------#
# getPICCData
# description: get the Cards manufacturing data
# input: object (hCard)
# return: hash table reference
#   hardware_vendor_id  => Vendor ID in hex
#   hardware_type       => Hardware Type
#   hardware_subtype    => Hardware Subtype
#   hardware_version    => Hardware Version Number
#   hardware_storage    => Storage size in bytes
#   hardware_protocol   => Hardware protocol
#   software_vendor_id  => Vendor ID in hex
#   software_type       => Software Type
#   software_subtype    => Software Subtype
#   software_version    => Software Version Number
#   software_storage    => Storage size in bytes
#   software_protocol   => Storage protocol
#   batch_number        => Batch Number
#   calendar_week       => Calendar week of production
#   production_year     => Year of production
#---------------------------------------------------------------------#
sub getPICCData
  {
  my $card = shift;

  my $response='';
  my $PICC = {};

  # get Hardware data
  $response = sendAPDU($card, '60');
  if (!$response) { return(undef); }
  # AF 04 01 01 01 00 1A 05
  $PICC->{'hardware_vendor_id'} = substr($response, 3, 2);
  $PICC->{'hardware_type'} = substr($response, 6, 2);
  $PICC->{'hardware_subtype'} = substr($response, 9, 2);
  my $HWVerMaj = substr($response, 12, 2);
  my $HWVerMin = substr($response, 15, 2);
  $PICC->{'hardware_version'} = hex($HWVerMaj).'.'.hex($HWVerMin);
  my $HWStorage = substr($response, 18, 2);
  #$PICC->{'hardware_storage'} = hex($HWStorage);
  $PICC->{'hardware_storage'} = $HWStorage;
  $PICC->{'hardware_protocol'} = substr($response, 21, 2);

  # get Software data
  $response = sendAPDU($card, 'AF');
  if (!$response) { return(undef); }
  $PICC->{'software_vendor_id'} = substr($response, 3, 2);
  $PICC->{'software_type'} = substr($response, 6, 2);
  $PICC->{'software_subtype'} = substr($response, 9, 2);
  my $SWVerMaj = substr($response, 12, 2);
  my $SWVerMin = substr($response, 15, 2);
  $PICC->{'software_version'} = hex($SWVerMaj).'.'.hex($SWVerMin);
  my $SWStorage = substr($response, 18, 2);
  #$PICC->{'software_storage'} = hex($SWStorage);
  $PICC->{'software_storage'} = $SWStorage;
  $PICC->{'software_protocol'} = substr($response, 21, 2);

  # get production data
  $response = sendAPDU($card, 'AF');
  if (!$response) { return(undef); }
  $PICC->{'batch_number'} = substr($response, 24, 14);
  my $ProdCW = substr($response, 39, 2);
  $PICC->{'calendar_week'} = $ProdCW;
  my $ProdYR = substr($response, 42, 2);
  $PICC->{'production_year'} = $ProdYR + 2000;

  return($PICC);
  }
[..]

my $hContext = new Chipcard::PCSC($Chipcard::PCSC::SCARD_SCOPE_SYSTEM, 0);
my @ReadersList = $hContext->ListReaders ();
my $ReadersName = $ReadersList[0];
$readers_states[0]={ 'reader_name' => $ReadersName };
# ignore first event
my @StatusResult = $hContext->GetStatusChange(\@readers_states);
foreach my $reader (@readers_states) { $reader->{'current_state'} = $reader->{'event_state'}; }

[..]

# Initialize  Card Object to read data from card
my $hCard = new Chipcard::PCSC::Card($hContext,$ReadersName,$Chipcard::PCSC::SCARD_SHARE_EXCLUSIVE,$Chipcard::PCSC::SCARD_PROTOCOL_T0);

# get UID from Card
my ($CARD_UID, $sw) = sendAPDUwithSW($hCard, 'FF CA 00 00 00');
print DATETIMESTRING().'   APDU state: '.Chipcard::PCSC::Card::ISO7816Error($sw).' ('.$sw.')'."\n";
print DATETIMESTRING().'   Card UID: '.$CARD_UID."\n";
[..]
my $piccData = getPICCData($hCard);
[..]
my $piccApp = getPICCApp($hCard);
[..]
$hCard->Disconnect($Chipcard::PCSC::SCARD_EJECT_CARD);
$hCard = undef;

Der nächste Schritt ist, eine Authentisierung hinzubekommen. Zum Verfahren findet man einige Beiträge im Netz – allerdings nie so richtig vollständig. [3a][3b][3c][4][5a][5b][6]

Die Desfire unterstützt als Verschlüsselungs Algorithmus DES, 3-DES und AES. Leider konnte ich keines der Beispiele im Netz mit Hilfe der Per Cipher Engins nachprogrammieren. Es scheint hier zu generellen Implementationsproblemen zu kommen. Egal was ich anwende CBC / noPadding via DES, 3-DES oder AES, nichts scheint die selben Ergebnisse zu reproduzieren wie in der Beispielen im Internet.

Ja, ich konnte das Licht im Büro ein und Ausschalten (hat meinen 5 Jährigen schwer beeindruckt) aber es ist mir dann doch zu unsicher nur mit der UID einer Karte etwas freizuschalten. Daher habe ich das Thema mit Perl zu Seite gelegt und angefangen Java zu lernen.

Ein paar Tage später konnte ich immerhin schon 3 der 5 auffindbaren Beispiele reproduzieren.

Die Idee aus Perl heraus ein Java zu triggern hatte ich tatsächlich kurz gehabt aber dann doch wieder verworfen. Wie schon gesagt, ich habe auch null Info von NXP.com bis heute.

Mahl ehrlich, das ist wie wen jemanden einen USB Stick verkauft der nicht vom Betriebsystem erkannt wird und man sagt dem Käufer auch nicht wie er ihn zum laufen bekommt, der der Treiber ist geheim. Meines Erachtens ziemlicher Schwachsinn.

Links:

[1] WikiPedia: Application Protocol Data Unit (APDU)
[2] CardWerk: ISO 7816 Smart Card Standard
[3a] http://stackoverflow.com/questions/14319321/how-can-i-do-native-authentication-in-desfire-ev1
[3b] http://stackoverflow.com/questions/14117025/des-send-and-receive-modes-for-desfire-authentication
[3c] https://n3vrax.wordpress.com/2011/07/23/des-algorithm-java-implementation/
[4] https://ridrix.wordpress.com/2009/09/19/mifare-desfire-communication-example/#comment-87
[5a] http://database.developer-works.com/article/15751843/Mifare+DESfire+card+Authentication!!!!!
[5b] https://community.oracle.com/thread/1751843
[6] http://stackoverflow.com/questions/21257442/mifare-desfire-ev1-authentication-using-aes

RFID Chipauswahl und der erste RFID Reader

Für das Zugangs Kontrollsystem via RFID braucht man nun auch die passende KArte.

Leider gibt es eine Fülle unterschiedlicher RFID Chips und Frequenzen.

Relativ schnell habe ich mich aber auf 13,56MHz eingeschossen.

Die Chipauswahl war etwas schwieriger, nach aufstellung der wichtigsten Chips und deren features habe ich mich für den „MIFARE DESFire EV1“ entschieden.

Der chip scheint, nach eineigen Recherchen, der Standard für solche Systeme zu sein. Zudem hat er jede menge Speicherplatz.

Nun brauch ich nur noch ein Gerät das die Dinger beschreibt. Und ein paar Testchips.

Ich habe mich für einen „ADRBv2 USB NFC/RFID Leser“ entschieden, da dieser von der libnfc unter Linux unterstützt wird. Wie sich später herausstellte war die Investition wohl umsonst.

Leider habe ich den RFID Leser nicht unter meiner Ubuntu VM zum fliegen bekommen, auch habe ich einige Zeit damit verbracht das Ding mit einen Raspberry PI B+ um arbeiten zu bewegen. Leider ebenfalls ohne Erfolg. Die mitgelieferten Treiber liesen sich, auch nach diversen manuellen eingriffen, nicht compilieren.

Nach freigabe durch meinen Finanzminister habe ich dann das „ChipMan Starter-KIT“ der Firma MB-Sys GmbH gekauft. Da war dann eine Software dabei, ein paar Testkarten und ein „SCM SCL011 USB Reader“.

Der Lief dann unter Windows mit der Software.

Erste Erfolge: Ich kann eine leere RFID Chipkarte einlesen.

Ich habe gelernt, die Desfire EV1 Organisiert sich in „Applikationen“ und „Dateien“. Dann hörte es auf bei mir. Das Schreiben mit der Software hat nicht ganz so geklappt wie ich erhofft hatte und wenn, was sollte ich schreiben.

Nun, aber was mir gelungen ist, ich habe den Reader via PC/SC Treiber auf dem Raspberry zum laufen gebracht.

Mit dem Perl Modul pcsc-perl konnte ich sogar Anfangen die RFID Karten auszulesen.

Aber damit gingen die Schwierigkeiten un richtig los.

Eine neue Haustüre

So, das ist der erste Beitrag in diesem Blog. Grund ist ein neues Projekt welches ich in meinem privaten Umfeld betreibe.

Auslöser ist, dass sich die Haustüre in unserem Haus sich nicht mehr richtig schließen liese.

130925HaustuerSchlossRenningen 011

Wir haben uns nun, nach einigen hin und her (ist auch ca. 1 Jahr ins Land gegangen), dazu durchgerungen nun endlich eine neue Türe anzuschaffen.

Nun, aber wenn dann gleich was richtiges, oder?

Da ich ja die meißte Zeit bei Großkunden unterwegs bin, ist mir der Zugang in Räumlichkeiten via RFID Chipkarte, gängig und da hab ich mir überlegt dass ich das auch zu Hause so haben möchte.

Nach meinem Empfinden sind die Vorteile gegenüber anderen Zugangsmedien durchaus gegeben.

Biometrische Verfahren sind Teilweise leicht zu knacken oder sind recht empfindlich bei Veränderung der „biometrischen“ Merkmale. Oder das Gesamtsystem wird so teuer dass es nicht mehr bezahlbar wird (für einen einfachen Personenhaushalt).

Nun, das Ziel RFID Chipkarte war nun gesetzt.

Wir haben uns bei der Haustüre für die Firma Biffar entschieden. Mahl ehrlich, die dinger sind echt geil aber auch nicht ganz billig.

Leider konnte uns Biffar keine RFID Lösung anbieten, wir sind trotzdem bei Biffar geblieben.

Für die Ansteuerung einer Türe muss ein Motor rein (das treibt den Preis beträchtlich nach oben). Konnte uns Biffar aber bieten.

Soweit, so gut. die Idee war geboren und die Grundlagen waren gesetzt. Die Türe kam nun vor ein paar Monaten und ist nun montiert.

DSCN1337

Nach der Besitigung  der ein oder anderen Mängel hinsichtlich der Elektronik, kann die Türe nun angesteuert werden.

20150612_185756

Alles weiter in den anderen Beiträgen.