domenica 28 ottobre 2012

Controllo degli accessi con Raspberri Pi - Installazione del software

Bene, ora che sapete costruire la board aggiuntiva e una vaga idea di come funzioni il software, è ora di installarlo e vederlo in azione.

Per prima cosa dovete scaricare i sorgenti sul Raspberry da github. Se non avete git, fate che installarlo (pacchetto git-core) che è comunque una dipendenza (lo usa lo script di aggiornamento firmware, rpi-update).
A questo punto lanciate
git clone https://github.com/pierinz/citofonoweb.git
per ottenere l'ultima versione di Citofonoweb, e
cd citofonoweb
per entrare nella cartella appena creata.

Ora possiamo dare un'occhiata ai contenuti:

- LICENSE, README.md e TODO contengono le informazioni relative al software;
- la cartella examples contiene esempi di file di configurazione, nello specifico aiuta a configurare lighttpd;
- il Makefile ovviamente serve per compilare e installare il tutto;
- tutto quel che resta sono i sorgenti.

Prima di procedere con l'installazione bisogna installare le dipendenze:
apt-get install lighttpd php5-cgi php5-cli php5-sqlite git-core rsync lsb-release usbutils binutils at psmisc diffutils ntpdate sqlite3
Inoltre, bisogna scaricare e compilare i sorgenti che forniscono il comando "gpio" (sul sito https://projects.drogon.net/raspberry-pi/wiringpi/download-and-install/).
Una volta fatto, basta lanciare make && make install.

Se avete eseguito tutti i passaggi correttamente, non dovreste aver ottenuto errori. In questo caso, potete configurare lighttpd secondo le direttive che trovate nella cartella examples, e riavviarlo con /etc/init.d/lighttpd restart.

Infine, aprite un browser sul vostro PC e puntatelo su http://indirizzoraspberry/Citofonoweb per accedere all'interfaccia web.

domenica 21 ottobre 2012

Controllo degli accessi con Raspberri Pi - Acquisizione dati

Una delle condizioni che avevo imposto per sviluppare un prodotto sensato era il supporto del maggior numero possibile di dispositivi di autenticazione.



Inizialmente avevo pensato di lavorare con un lettore badge magnetico con interfaccia seriale o TTL, perché è facile trovare guide per interfacciarne uno con arduino (per esempio questa). Il problema è che quest'approccio è molto poco estendibile, e vincola all'utilizzo di un prodotto preciso.

Esaminando più a fondo il problema, ho notato che la maggior parte dei lettori USB viene fornito in due modalità:
- provvisto di driver proprietari (ed software di sviluppo)
- configurato in emulazione tastiera
La modalità di emulazione tastiera è estremamente interessante perché per il sistema operativo il device appare come una comunissima tastiera, e quindi è possibile usare praticamente qualsiasi device che rispetti lo standard HID senza preoccuparsi di drivers specifici.

Il kernel Linux contiene i drivers HID, e quando una periferica di questo tipo viene collegata crea un device in /dev/input. Se avete un pc desktop con qualsiasi distribuzione Linux, potete usare il comando
ls /dev/input/by-id/
per vedere tutte le periferiche di input collegate (mouse, tastiera, joystick e altre periferiche).
Generalmente i device sono creati con nomi quali event0, event1 e così via, ma nella cartella /dev/input/by-id/ vengono creati dei collegamenti con nomi più comprensibili a un essere umano:

~ $ ls /dev/input/by-id/ -l
totale 0
lrwxrwxrwx 1 root root  9 21 ott 19.57 usb-046d_Gaming_Keyboard_G110-event-if01 -> ../event9
lrwxrwxrwx 1 root root  9 21 ott 19.57 usb-046d_Gaming_Keyboard_G110-event-kbd -> ../event8
lrwxrwxrwx 1 root root  9 21 ott 19.57 usb-LOGITECH_G110_G-keys-event-kbd -> ../event7
lrwxrwxrwx 1 root root 10 21 ott 19.57 usb-QCM_Laptop_Integrated_Webcam_HD-event-if00 -> ../event12
lrwxrwxrwx 1 root root 10 21 ott 19.57 usb-Saitek_Cyborg_R.A.T.5_Mouse-event-mouse -> ../event10
lrwxrwxrwx 1 root root  9 21 ott 19.57 usb-Saitek_Cyborg_R.A.T.5_Mouse-mouse -> ../mouse0
 Ora qualcuno di voi potrebbe pensare: "Ora che abbiamo il device file, per acquisire i dati non resta che fare cat /dev/input/eventX!" e, in effetti, era venuto in mente pure a me.
Tuttavia questo metodo è valido solo per testare se davvero state leggendo dei dati dal dispositivo, poiché dal devices vengono lette una serie di strutture dati che rappresentano tutte le informazioni relative all'evento:
- timestamp
- codice dell'evento
- tipo dell'evento
- valore

Cercando più a fondo, ho trovato questa guida che spiega le basi per interagire con il sottosistema di input di Linux. Io non capisco assolutamente niente di C, ma con un po' di ingegno e molto copia-incolla sono riuscito ad estrarre i dati che cercavo.

A questo punto, rimaneva un'ultima questione da esaminare: essendo il lettore di badge a tutti gli effetti trattato come una tastiera, quando viene strisciato un badge il suo valore viene inviato all'applicazione aperta. Se avete il blocco note aperto, vi apparirà il contenuto della banda magnetica.
Essendo CitofonoWeb un'applicazione headless questo non era un grave problema, la sequenza di tasti sarebbe stata inviata alla tty1 in attesa di username e password, che ovviamente li avrebbe rifiutati.
Tuttavia ignorare questo comportava due conseguenze fastidiose:
- milioni di accessi falliti in /var/log/auth.log
- impossibilità di fare manutenzione con una normale tastiera mantenendo il servizio attivo

Ho quindi cercato ancora più a fondo e ho scoperto l'opzione EVIOCGRAB: in breve, permette di acquisire dati dal dispositivo in modalità esclusiva, senza che gli eventi letti si propaghino oltre.

A questo punto, mettendo assieme tutte queste conoscenze sono riuscito a produrre questo:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <dirent.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/select.h> #include <sys/time.h> #include <termios.h> #include <signal.h> #include <linux/input.h> #define EV_PRESSED 1 #define EV_RELEASED 0 #define EV_REPEAT 2 void handler (int sig) { fprintf (stderr,"exiting...(%d)\n", sig); exit (0); } void perror_exit (char *error) { perror (error); handler (9); } int main (int argc, char *argv[]) { setbuf(stdout, NULL); struct input_event event; int fd, rd, value, size = sizeof (struct input_event); char name[256] = "Unknown"; char *device = NULL; //Setup check if (argv[1] == NULL){ fprintf(stderr,"Please specify (on the command line) the path to the dev event interface device\n"); exit (0); } if (argc > 1) device = argv[1]; //Open Device if ((fd = open (device, O_RDONLY)) == -1) fprintf (stderr,"%s is not a vaild device.\n", device); //Print Device Name ioctl (fd, EVIOCGNAME (sizeof (name)), name); fprintf (stderr,"Reading From : %s (%s)\n", device, name); //Uso esclusivo ioctl (fd, EVIOCGRAB, 1); while (1){ /* how many bytes were read */ size_t rb; /* the events (up to 64 at once) */ struct input_event ev[64]; rb=read(fd,ev,sizeof(struct input_event)*64); if (rb < (int) sizeof(struct input_event)) { perror("evtest: short read"); exit (1); } int yalv; for (yalv = 0; yalv < (int) (rb / sizeof(struct input_event)); yalv++) { if (EV_KEY == ev[yalv].type){ //printf("%ld.%06ld ", ev[yalv].time.tv_sec, ev[yalv].time.tv_usec); //printf("type %d code %d value %d\n", ev[yalv].type, ev[yalv].code, ev[yalv].value); //Stampa solo al keydown if (ev[yalv].value==0) printf("%d\n", ev[yalv].code); } } } close(fd); return 0; }

Lo stesso programma potete trovarlo su GitHub all'interno della pagina del progetto CitofonoWeb.
Domani (tempo permettendo) spiegherò più approfonditamente come funziona questo programma C, e come viene usato dal demone di acquisizione dati.

giovedì 18 ottobre 2012

Controllo degli accessi con Raspberri Pi - Collegamenti elettrici

Come preannunciato, oggi spiegherò come costruire la board aggiuntiva che trasforma il Raspberry Pi in CitofonoWeb.

La board una volta assemblata
Come avevo scritto ieri, i componenti necessari sono:
- 1 scheda di prototipazione
- 1 ULN2003 o ULN2803
- 1 relé con bobina a 5V
- 1 led verde
- filo elettrico, stagno, saldatore e quant'altro 
- zoccoli, morsetti e cose simili

Lo schema elettrico è questo:



Come potete notare i primi collegamenti sono abbastanza semplici, il pin 17 pilota un led di stato che si illumina quando la board è in funzione, il pin 21 (opzionale) può gestire un bottone per aprire la porta (senza autenticazione), il pin 23 illumina un led rosso (per indicare accesso negato).
I pin 18 e 24 richiedono una piccola spiegazione aggiuntiva.

I GPIO del Raspberry funzionano a 3.3V con una corrente massima di 50mA, assolutamente inadatta a pilotare un relé, per questo motivo hanno bisogno di essere "amplificati" a 5V.
L'uscita 5V del Raspberry è perfetta a questo scopo perché può erogare circa 300mA (potete trovare ulteriori informazioni qui), però non può essere pilotata.
Usiamo quindi un array di transistor darlington (l'ULN 2003): quando viene "acceso" il GPIO 18, il pin 1 dell'ULN viene alimentato, e manda a terra il pin del lato opposto, ovvero il 16. Quando il pin 1 non è alimentato, il circuito dalla parte del pin 16 rimane aperto.

Come bonus l'ULN2003 è fornito di diodi, che evita di dover aggiungere un diodo al relé per evitare il contraccolpo induttivo della bobina.

mercoledì 17 ottobre 2012

Controllo degli accessi con Raspberri Pi - Introduzione

Preambolo

Dunque, qualche tempo fa nell'azienda in cui lavoro avevano tirato fuori dal cappello magico l'idea di prendere tutte le porte esterne e sostituirne la vecchia banale serratura con un sistema di apertura a tessera magnetica.

Controllo accessi con lettore RFID

Subito ci siamo scontrati con numerosi problemi: innanzitutto le porte sono parecchie e sono molto distanti tra loro, e il numero di dipendenti da abilitare su ciascuna era di gran lunga superiore alla decina, dunque era fondamentale un sistema centralizzato per configurare gli accessi.
Inoltre, si voleva poter configurare per ogni porta e ogni dipendente un orario di ingresso. E soprattutto, poter riutilizzare i badge già utilizzati per il rilevamento presenze (e non dover inserire i relativi dati da capo).

A questo punto ci è stato evidente che una soluzione sviluppata ad hoc sarebbe stata più razionale ed economica che cercare di creare un qualche accrocchio unendo soluzioni preesistenti.
È nato così il progetto "CitofonoWeb" (dopo capirete il significato del nome), sotto licenza GPL-2.

Come funziona

Il funzionamento volevo che fosse più semplice possibile, ma che allo stesso tempo avesse un'elevata compatibilità e fosse estendibile senza troppi grattacapi. Con un occhio di riguardo anche al costo finale dell'attrezzatura.

La prima cosa che ho previsto è che ogni Raspberry gestisca una sola porta. Questo perché le uscite sono limitate, e perché farne gestire più di una avrebbe reso più complesso il codice. Inoltre, è molto raro che due porte siano così vicine da essere collegate allo stesso Raspberry.

La seconda cosa su cui ho ragionato è che gli accessi devono essere configurabili in maniera comoda, e per questo motivo il Raspberry deve essere collegato in rete locale, tuttavia a parte la configurazione iniziale dovrebbe poter funzionare anche off-line.
Bisogna però considerare che essendo senza RTC (l'orologio interno), il dispositivo deve sincronizzarsi con un time server per sapere la data e l'ora. In alternativa, è possibile montare un RTC con meno di una decina di euro. Questo rende possibile anche l'eventuale collegamento del device alla rete locale via wireless.

La terza condizione che mi premeva era di supportare il maggior numero possibile di lettori di badge senza dover scrivere una quantità allucinante di codice.

A questo punto ho considerato il flusso di lavoro, che ho immaginato simile a un citofono: quando qualcuno suona al campanello, chi risponde deve riconoscere la persona alla porta e poi decide se aprire o no.
Allo stesso modo, quando un utente striscia il suo badge, il Raspberry prende i dati dal MSR (lettore banda magnetica), li elabora, li confronta con i suo database e infine decide se aprire la porta.

Il RaspBerry Pi (sotto) e la scheda aggiuntiva di CitofonoWeb (sopra)

Sviluppo hardware - componenti usati

Componenti fondamentali:
- 1 elettroserratura (o incontro elettrico)
- 1 MSR
- 1 Raspberry Pi
- 1 scheda SD da almeno 1 GB (compatibile con il Raspberry)
- 1 cavo flat per l'uscita GPIO del Raspberry
- 1 scheda di prototipazione
- 1 ULN2003 o ULN 2803, come più vi piace
- 1 relé con bobina a 5V (io ho usato il Finder 32.21.7.005.2000, scegliete in base all'elettroserratura)
- 1 alimentatore 5V con almeno 1000mA (anche da 800mA potrebbe bastare, ma meglio stare sicuri)
- 1 cavo microUSB
- 1 cavo ethernet
- 1 alimentatore elettroserratura
- 1 led verde
- 1 scatola di derivazione (se non avete già un posto dove mettere il tutto)
- filo elettrico, stagno, saldatore e quant'altro 
- per un lavoro ben fatto, due zoccoli per il relé e l'ULN2003/2803, e qualche morsetto

Ci sono inoltre parecchi elementi opzionali, potete scegliere se montarli o no a vostra discrezione (capirete a cosa servono leggendo il resto):
- 1 cicalino (richiede relé aggiuntivo)
- 1 led rosso
- 1 led giallo
- 1 pulsante
- 1 resistenza da 10KΩ
- 1 modulo RTC

Adesso iniziate a meditarci su, ci vediamo domani con la Parte 1 - Collegamenti elettrici.

martedì 16 ottobre 2012

Raspberry Pi, miglior acquisto di sempre

Probabilmente vi hanno già stressato a sufficienza da altre parti con questa notizia (peraltro datata) ma, dato che la maggior parte di ciò che scriverò qui riguarda questo arnese, ve ne parlo brevemente.

Il Raspberry Pi è un PC in miniatura in grado di far girare distribuzioni GNU/Linux quali Debian, Fedora, Arch, Gentoo e tutte quelle che supportano l'architettura armv7.


Dispone di un processore ARM, 256 MB di memoria RAM (da poco pare ne monti 512), scheda video con connettore HDMI e RCA, scheda audio, 2 porte USB, una porta ethernet e come unità disco richiede una SD card. In più, ha una manciata di I/O programmabili (GPIO) vagamente paragonabili a quelli presenti su Arduino (che è comunque un prodotto completamente diverso).

Le connessioni del Raspberry Pi


Ma, dato che di board ARM che supportano Linux ne esistono già a pacchi (BeagleBoard, BeagleBone, Pandaboard e chi più ne ha più ne metta), perché tanto entusiasmo?
Per il motivo più banale del mondo: costa estremamente poco (circa 40 euro).
Difatti il primo stock è andato a ruba, e continua a vendere tanto che su RS e Farnell spesso non è direttamente disponibile.

Date le piccole dimensioni e la discreta capacità di calcolo, è possibile utilizzarlo per scopi quali:
- media center con XBMC (è in grado di riprodurre alcuni formati video in alta definizione 1080p)
- webserver casalingo
- NAS con un hard disk usb (anche se è blasfemia un NAS con scheda di rete 10/100)
- piattaforma per retrogaming (con molto impegno, probabilmente ne riparlerò in futuro)

Su http://elinux.org/RPi_Hub ci sono tutte le informazioni necessarie su ogni singolo componente, sulle periferiche compatibili e sulle distribuzioni disponibili. Un ottimo punto di partenza per esplorare le potenzialità di questo dispositivo.

Domani parlerò di un progetto basato sul Raspberry Pi che ho sviluppato per l'azienda in cui lavoro e che verrà rilasciato con licenza GPL-2.

Cosa è questo?

E così, dopo anni di rimandi e posticipi, infine apro un blog.
L'idea di base è quella di riempire questo spazio con guide, nerdismi, disavventure informatiche e cose varie, ma dato il mio spiccato amore per il nonsense chi sa cosa ci finirà dentro.
In ogni caso non perdete tempo a leggere queste futilità, ma leggete i post successivi.