This is an old revision of the document!
Table of Contents
BrmDoor
~~META: status = active &relation firstimage = :project:pir.jpg ~~
For hackerspace more secure and without the annoyance of physical keys. DIY digital lock control, open/closed space status monitor and burglar alarm.
System architecture: Raspberry Pi + Adafruit PN532 shield. Supports ISO14443 cards (Mifare Classic, Desfire, Yubikey, you could even use Visa/Mastercard NFC payment cards; Android NFC Host Card Emulation could be used as well with some changes). Authentication: via UID, challenge-response with Yubikey Neo, signed public-key cryptography (Ed25519) messages with Desfire cards.
Unlocking the Door
Executive summary, how to get in without a key - arrange registering your RFID card (ISO-14443A, e.g. Mifare Classic, Mifare DESFire) with council at the meetup (or over mail rada _at_ brmlab.cz). After adding your card to brmdoor DB, you will be able to unlock the door by placing the card next to the reader.
BrmDoor Hardware
- We have Adafruit PN532 NFC/RFID Controller Shield for Arduino. (lessons learned: do not use http://www.seeedstudio.com/depot/1356mhz-rfid-module-iosiec-14443-type-a-p-196.html).
- MCU/controller: Raspberry PI (all versions supported - 1, 2, 3)
- OS: Raspbian or Ubuntu (other may work as well if you can get required packages to build and install)
- Lock device - BERA-E electromagnetic lock:
- From inside, it is possible to open the door anytime by just pushing the handle.
- From outside, it is possible to open the door by turning the lock by the key, OR by pushing the handle if the voltage is applied.
- Lock specs say 12-24V should be used, but from experience 12 V is not enough. Use 24 V.
Communication is over SPI: both SEL0 and SEL1 are shorted which turns communication to be over SPI.
Documentation of Adafruit PN532 shield (our revision is 1.2):
BrmDoor Firmware
Source repository: https://github.com/hiviah/brmdoor_libnfc
List of authorized cards
Card list is on brmlab VPS (vps.brmlab.cz) are exported from JendaSAP, on /root/sap/cards.txt
.
Adding a new card to JendaSAP and import to brmdoor
Put the card next to the reader, then look into a log (on brmdoor raspi in /root/brmdoor_libnfc/brmdoor.log
) for Unknown UID
line.
Login to vps.brmlab.cz. In /root/sap/members
, find member's file and add line with the card UID (4, 7 or 10 byte UID), e.g.
card 0102ab89
On vps.brmlab.cz
in /root/sap
directory, run parse.py
script:
cd /root/sap parse.py
This will create cards.txt
. Copy the cards.txt
to brmdoor and run on brmdoor raspi:
cd brmdoor_libnfc/; ./import_jendasap_cards.py /path/to/cards.txt brmdoor.sqlite''
No need to restart brmdoor daemon. Note that the import can take even a minute since the brmdoor Raspberry 1 is fucking slow.
members
directory on vps.brmlab.cz
.
In the members
directory, commit the changed card with
git commit -m "Added card for member Ctulhu" 1234_member_uid_file
OPEN/CLOSED switch with update of topic on IRC and SpaceAPI format on VPS
In brmdoor_nfc.config
, look at the section [open_switch]
. IRC must be enabled in [irc]
section for status
update to work.
The first part of the topic until |
character will be replaced by OPEN/CLOSED (if there is no pipe character,
OPEN/CLOSED will be prepended).
Configuration needs setting a file that is read once per second, open_value
determines which value means
“open”. Thus you can use any daemon/cron script/whatever that just writes a predetermined value to file which
will be read by brmdoor daemon.
For a simple switch (that just closes/opens the electrical connection) connected to GPIO PINs, you need to
configure a PIN in input mode and turn on internal pullup on the input PIN. An example of this is in the
brmdoor_start.sh
script below. Connect one cable of the switch to an input PIN and the other to the ground.
#!/bin/bash export PIN=22 if [ '!' -d /sys/class/gpio/gpio$PIN ]; then echo $PIN > /sys/class/gpio/export echo in > /sys/class/gpio/gpio$PIN/direction fi python -c "import wiringpi; wiringpi.wiringPiSetupGpio(); wiringpi.pinMode($PIN, wiringpi.INPUT); wiringpi.pullUpDnControl($PIN, wiringpi.PUD_UP)"
If the switch is in open position (connected to ground), the “open” value will be 0, the close value will be 1 (effect of the internal pull-up).
The numbering scheme is the same as in the lock configuration (BCM GPIO numbering,
https://projects.drogon.net/raspberry-pi/wiringpi/pins/). A copy of the mapping is in
gpio_vs_wiringpi_numbering_scheme.png
file) in case the webpage goes away.
Changing OPEN/CLOSED status remotely with software
Any IRC user in #brmlab
channel can change the topic by using the /topic
command. This value will stay
until the physical switch changes the value.
Reporting/uploading status in SpaceAPI format
Currently since v 0.2 brmdoor can upload the status and information in SpaceAPI.net format.
The status JSON is mapped currently is mapped to https://brmlab.cz/spaceapi/status.json. The interesting non-static part of json is in under “state” key - “open” (boolean) and “lastchange” (Unix timestamp).
PIN assignments
General GPIO PIN assignments are configurable, communication (SPI/I2C) must follow the definition in Raspberry Pi pinouts. Raspi pinouts for all versions: http://pi4j.com/pins/model-3b-rev1.html
Numbering scheme used by brmdoor for lock and open switch (based on BCM GPIO numbering, different from P1 header physical PIN numbers): https://projects.drogon.net/raspberry-pi/wiringpi/pins/
PIN assignemnts (physical PINs on P1 header, with BCM GPIO numbers used in config):
- 5V power into Raspberry: physical #1
- Ground from power source to Raspberry: physical #9
- 5V power out into Adafruit PN532 reader: #4
- Ground for Adafruit PN352: physical #6
- BERA-E lock open/close: physical #22, BCM GPIO #25
- Open/close switch input PIN: physical #15, BCM GPIO #22
- Ground for open/close switch: physical #25
- SPI pins for Adafruit PN532 reader - SPI PINs on Raspberry - physical #19, #21, #23, #24
GitHub, last commits
- Added shell script for masochits that syncs card data from VPS by hiviah (2023/11/16 23:44)
- Update photos of installation by hiviah (2023/10/05 23:06)
- Handle badly encoded incoming messages better by hiviah (2023/10/03 17:45)
- Get rid of pysftp, it was pretty broken, now use paramiko directly by hiviah (2023/09/16 19:51)
- Revert back invertion of signals, 1 opens lock, 0 closes by hiviah (2022/10/11 18:31)
Photos of cable connections of Raspi + PN532 shield (location Ke kaplicce 18)
Brmdoor HOWTO (displayed after you login as root, in /etc/motd)
Current brmdoor directory is `/root/brmdoor_libnfc` Config is in the file: `/root/brmdoor_libnfc/brmdoor_nfc.config` Full README is at https://github.com/hiviah/brmdoor_libnfc/blob/master/README.md A preferred way to add a card is to add it to JendaSAP, then import (see below). ## Import cards.txt from JendaSAP's cards.txt (WARNING: THIS WILL OVERWRITE THE TABLE WITH UIDs) cd brmdoor_libnfc/ ./import_jendasap_cards.py cards.txt brmdoor.sqlite If `brmdoor.sqlite` does not exist, it will be created. If it exists, the `authorized_uids` table will be replaced with UIDs/nick pairs from `cards.txt` (other tables are not touched). ## Adding card by UID Note: this is useful for adding card temporarily since import from JendaSAP will remove it - find out the UID: 1. put the card near the reader, 2. as root, look into the log, currently /root/brmdoor_libnfc/brmdoor.log - look into the log for the unknown UID, look for `Unknown UID` message - the following command will add a card as authenticated by UID, for other methods see full README cd brmdoor_libnfc/ ./brmdoor_adduser.py -c brmdoor_nfc.config -a uid 1234ABCD SomeUserName ## List authorized cards UIDs + nicks from DB sqlite3 ~/brmdoor_libnfc/brmdoor.sqlite 'select nick, uid_hex from authorized_uids;' ## Start/stop daemon systemctl start brmdoor.service systemctl stop brmdoor.service Systemd unit location: `/etc/systemd/system/brmdoor.service`
Features
Source: brmdoor_libnfc
Requires libnfc, libfreefare and WiringPi2
Features:
- Clean, documented and extensible code
- Authentication data is stored in SQLite DB - no need to restart daemon to make any change; extensible DB schemas
- NFC smartcard communication support (ISO 14443-4)
- Multiple authentication schemes supported
- simple authentication by UID
- Authentication with EdDSA (Ed25519 signatures) for Desfire cards (can be used with Host Card emulation on Android phones)
- Dedicated configuration file and logging facilities
Missing features:
- No sound produced (can be fixed via WiringPi)
- Setting topic is not finished (python-irc has fairly bad API to retrieve topic)