Initialisierung von Karten (2nd try)

Im Moment bin ich an der Erstellung des „Card Management Systems“.
Das Thema mit der DESFire Kommunikation hat mich nun wieder eingeholt. Daher habe ich wieder angefangen nach den DESfire spezifischen APDUs zu suchen.

Um an die NXP Dokumentation „MIFARE DESFire – Implementation hints and examples,document number: 094532″ heranzukommen, habe ich nun auch einen Account im NXP Docstore beantragt. Mal sehen ob die sich melden, denn zu meinem eröffneten Ticket bei NXP.xom gab es in den letzten 3 Monaten keine Reaktion (selbst nach Rückfrage).

Den logischen Ablauf stelle ich mir wie folgt vor:

  1. RFID tag formatieren
  2. PICC Applikation formatieren
  3. Keys ablegen
  4. Kommunikation mit RFID tag verschlüsseln
  5. PICC Applikation konfigurieren (z.B. Random UID)
  6. Applikation anlegen und Konfigurieren
  7. Kommunikation Applikation mit Keys sichern
  8. File anlegen
  9. Kommunikation File mit Keys sichern
  10. Initiale Daten in File schreiben

Kaufsoftware oder selber machen

Die Frage stellt sich mir auch wieder. Es gibt einiges an Kaufsoftware mit der man die Karten konfigurieren kann. [1][2] Allerdings sind diese relativ teuer. Der ChipMan kostet (mit DESFire Funktionalität) immerhin 798 Euro (Stand November 2014). Die Vollversion sogar 1598 Euro. Nichts desto trotz frage ich derzeit auch die Preise für BadgeMaker an.

Parallel hierzu versuche ich natürlich mit der Feig SDK weiter zu kommen. Leider ist das SDK nicht wirklich gut Dokumentiert. Hauptinformationsquelle ist das Tutorial Dokument das allerdings nicht vollständig ist.
Am Montag habe ich den tagHandler für MIFARE DESfire entdeckt, mal sehen ob ich hier weiter komme. Ich habe gemerkt das mit dem Protokoll wissen (APDUs) das Feig SDK etwas besser zu durchschauen ist. Daher auch der erneute Versuch an die MIFARE Doku zu kommen. Meine Internet-Recherche hat allerdings wieder ein paar interessante Quellen aufgetan (siehe [3] bis [6]).
Wenn ich nicht weiterkomme muss ich wohl wieder mal den technischen Support der Feig bemühen mir zu helfen.

Links:

[1] MP-Sys – ChipMan: http://www.mpsys.de/
[2] ScreenCheck BV – BadgeMaker (mit Encode add-on) http://en.badgemaker.info/
[3] Ridrix’s Blog – APDU commands: https://ridrix.wordpress.com/tag/mifare-desfire/
[4] NXP – MIFARE DESFire as Type 4 Tag: http://www.nxp.com/documents/application_note/AN11004.pdf
[5] Jérémie Laval’s page – A Philips Datasheet: http://neteril.org/files/M075031_desfire.pdf
[6] SmartCard Networking Forum – DESFIRE Specification: http://www.scnf.org.uk/smartstore/LASSeO%20docs/DESFIRE%20Specification%20V1%200.pdf

Gehäuse fertig, Open Collector vs Rellais und PiUSV+

Gehäuse

Also nun ist es am Wochenende doch noch fertig geworden. Blau-Metallic lackiert sieht es schon recht schick aus.

20150912_11204020150912_12090420150912_120914

PiFace Digital 2

Nach dem Zusammenbauen habe ich den OpenCollector Ausgang nochmals geprüft, dabei ist mir aufgefallen dass der Ausgang auf Masse gezogen wird wenn der Server aus ist. Das ist nun doch etwas ungünstig, denn bei einem Server Ausfall würde ja dann die Türe aufgehen. Daher bin ich nun doch kurzfristig umgestiegen auf das Relais.
Da der Traffo genug Power hat (10 Ampére) konnte ich das PiFace Digital 2 auch direkt mit Strom versorgen.

PI USV+

Leider ist mir noch etwas aufgefallen für das ich derzeit noch keine Lösung habe. Der Akku der für die Notfall-Stromversorgung da sein sollte funktioniert nicht wie gewünscht. Die PI USV+ hat 4 Status LEDs. Aber das Bild das ich hier sehe gibt es in der Doku nicht.

In der Doku (Kapitel 2.1, Seite 7) steht folgendes:

  • LED1 (Rot): Betrieb über Akku
  • LED2 (Gelb): Status Anzeige des Akkus. LED Blinkt: Akku wird geladen, LED leuchtet dauerhaft: Akku ist voll
  • LED3 (Grün): Status Anzeige PiUSV+. LED Blinkt: USV funktioniert ordnungsgemäß
  • LED4 (Grün): Betrieb über Primäreingang

Nun zeigt sich bei mir folgendes Bild:

  • LED1: blinkt schnell
  • LED2: ist aus
  • LED3: blinkt langsam
  • LED4: leuchtet dauerhaft

Das sehe ich, ob ich nun einen Akku dran habe oder nicht. Als Akku verwende ich derzeit einen Panasonic NCR18650B Lithium-Ionen Akku (3400mAh).

Gemäß PiUSV+ Doku (Kapitel 2.2, Seite 7) muss der Akku folgende Spezifikationen aufweisen:

  • Technologie: Lithium Ionen (LiIon) oder Lithium Polymer (LiPo)
  • Zellen: 1
  • Kapazität: min. 300mAh
  • Spannung: +3.7V
  • Entladestrom: min. 3A
  • Ladespannung: +4.2V
  • Ladestrom: 100mA

sollte demnach passen. Aufgeladen ist der Akku auch. Keine Ahnung was da jetzt los ist. Das Gehäuse lasse ich aber bis zur Lösung wohl offen.

Hab auch mal bei de PiUSV Facebook Seite nachgefragt (Link zum Post).

Links

 

Gehäuse „fast“ fertig

20150911_132828

Das Servergehäuse wär quasi „fast“ fertig. Ich möchte es jetzt noch lackieren damit es gut aussieht. Aber funktional wäre es schon einmal.

Im Moment bin ich mir auch noch nicht sicher ob ich noch einen Lüfter einplanen muss. Das überlasse ich der Temparatur Auswertung. 20150911_131817

Die Anschlüsse und Kabel sind zwischenzeitlich auch alle verlötet oder gekrimpt. Sobald das Gehäuse dann so aussieht wie gewünscht, geht es an das zusammenschrauben.

Wie geht’s weiter

Hier nur ein sc2015-09-10-Architektur-Schaubildhneller Bericht zum Stand der Dinge.

Den aktuellen Stand seht Ihr hier rechts auf dem bekannten Schaubild.
Folgende 2 Dinge sind als nächstes geplant:

  1. Die Fertigstellung des neuen Gehäuses für den Raspberry Server mit den ganzen Erweiterungen und notwendigen Anschlüssen.
  2. Die Entwicklung des Card-Management-Systems zur Initialisierung der Karten. (Application + File + Encryption)

Mr. Chekov – Energie!

7 Stunden habe ich gebraucht um unseren Sicherungskasten neu zu verdrahten.
Hauptausschlaggebend war, dass wir nur einen FI Schalter für das gesamte Haus hatten.
Das habe ich nun aufgelöst und 3 FI Schalter eingebaut. Hier konnte ich dann schön die Funktionen der Stromkreise verteilen.
Wir haben jetzt:

  • einen FI Schalter für alle Feuchträume und den Garten
  • einen FI Schalter für Anlagen und Geräte die nicht Ausfallen sollten (bei denen die Gefahr eines Fehlstroms qusi null ist)
  • einen FI Schalter für die restlichen Räume

Des weiteren habe ich den Traffo für den Motor der Haustüre eingebaut und einen zusätzliche Stromanschluß nebst Sicherung für die Server im Haushalt eingerichtet.

Leider ist mir das 10mm² Kabel gestern ausgegangen, darum musste ich etwas „pfuschen“ damit wir abends wieder Strom hatten. Das werde ich heute Abend wohl noch gerade ziehen müssen.

Das biegen der Radien für die Leitungen im Kasten war gar nicht so einfach, vor allem wenn der Teilweise bestückt ist. Ganz schlimm war das neu verlegen der Zuleitungen. Der Elektriker hat hier damals eine massive 10mm² Leitung verlegt und keine flexible. Nicht ganz einfach eine Kupferstange zu biegen. Hat dann aber doch geklappt.

Hier ein paar vorher/nachher Bilder:

Vorher:

20150906_112419

Nachher:

20150906_142815

Vorher:

20150906_112353

Nachher:

20150906_170559

Vorher:

20150906_112347

Nachher:

20150907_174528

Und meine Frau hat natürlich hinterher gleich fleissig die Löcher gestopft:

20150906_193030 20150906_194543

Ich dremel mir mal ein Servergehäuse

Heute habe ich mich an das Servergehäuse gewagt und angefangen erste Löcher in das ding zu bohren. Der Erste Versuch mit der Trennscheibe auf dem Dremel ging leider schief. Da fehlt mir wohl die Übung und hab mich dabei verderemelt. Nun ja, es wird wohl ein wirklich sehr „individuelles“ Gehäuse werden.

Die vielen tollen Teile die ich bei Reichelt bestellt habe werde ich wohl in einem anderen Projekt einsetzen (sobald mir etwas eingefallen ist). Jedenfalls bekomme ich die Ganzen Delock Keystones gar nicht alle unter und was mich am meißten ärgert, der Ein-/Ausschalter mit dem Kaltgerätestecker ist ebenfalls zu groß. Da muss ich mir wohl was Neues einfallen lassen.

Ich werde dafür den Raspberry so einbauen dass ich zumindest an die Netzwerk und USB Schnittstellen komme. das kommt aber wohl erst morgen (oder an einem der nächsten Tage). Den HDMI werde ich mir wohl abschminken müssen.

20150904_172631 20150904_172636 20150904_172652

Kabel Verlegearbeiten

Nun war einen Monat Ruhe hier im Blog. Die Entwicklung am Zugangskontrollsystem ging trotzdem weiter.

  1. Programmierung:
    Das Auslesen der Kartendaten funktioniert zwischenzeitlich. Bislang nur die Karten ID. Der nächste Schritt ist nun die RFID Chips zu initialisieren damit diese vom System erkannt werden. Dann wird das Programm um die Applikationsdaten des chips ergänzt.
  2. Server:
    Da das gekaufte Hutschienengehäuse mit PI USV und I/O Board zu klein wurde werde ich nun ein eigenes Gehäuse entwickeln. Die Bestandteile sind heute angekommen. Werde bei Zeiten mal ein Foto davon machen.
  3. Strom für die Türe und verlegen der benötigten Datenleitungen:
    Das habe ich heute mit meiner Frau gemacht. Sie liebt es mit der HILTI große Löcher in Betonwände zu bohren.
    Die Kabel sind nun verlegt, sobald ich etwas Zeit habe werde ich die Leitungen auf     Funktion prüfen damit da nix schief geht.
    Dann mache ich mich an die Umgestaltung des Sicherungskasten.

Anbei noch ein paar Bilder von den heutigen Arbeiten.

20150826_11214420150826_11212420150826_12045220150826_11571620150826_112155

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); 
    }
}