RC522
system: device provider: sensor/rc522 introduced in v0.1 internalPull presence Arch restricted: arm GPIO: SCI
rc522 or rf522 are cheap NFC readers.
go-home
provides ability to read certain block of a data (16 bytes) to
compare with your pre-defined “pass-codes” to determine which user was authorized.
Example pinout
rc522 Pin | Line | RPi Pin |
---|---|---|
0 | SDA | 24 |
1 | SCK | 23 |
2 | MOSI | 19 |
3 | MISO | 21 |
4 | IRQ | 11 |
5 | GND | 6 |
6 | RST | 13 |
7 | +3.3V | 1 |
Configuration options
Param | Required | Type | Default | Description |
---|---|---|---|---|
bus | yes | int | 0 |
Bus ID to use |
device | yes | int | 0 |
Device ID to use. Final device address is /dev/spidev<bus>.<device> |
reset | yes | int | 13 |
Physical number of the reset (RST) pin |
irq | yes | int | 13 |
Physical number of the IRQ pin |
antennaGain | int | 4 |
Antenna gain (0-7) | |
sector | yes | int | 1 |
Sector number where the key is located |
block | yes | int | 0 |
Block number where the key is located |
key | yes | string | Byte-string representing encryption key | |
users | yes | map[string]string | List of key-value pairs with users and corresponding keys |
Supported properties
Property | Type | Description |
---|---|---|
on |
bool | Flag indicating whether user was successfully authorized |
user |
string | Name of the users from users configuration option |
Example
system: device
provider: sensor/rc522
name: nfc
bus: 0
device: 0
reset: 13
irq: 11
sector: 1
block: 0
users:
vlad: "407e3e663d556d5b587b4c527741337d"
key: "030e0f5c4123"
workerSelectors:
name: worker-static-1
Here
030e0f5c4123
is a byte-string, equals to[6]byte{3, 14, 15, 92, 65, 35}
from example below.407e3e663d556d5b587b4c527741337d
is a byte-string equals to@~>f=Um[X{LRwA3}
.
Configuring keys
To write your own secret you can use the following snippet.
Data is actually a
[16]byte
, for simplicitystring
is used.
package main
import (
"fmt"
"github.com/jdevelop/golang-rpi-extras/rf522"
"github.com/jdevelop/golang-rpi-extras/rf522/commands"
"github.com/sirupsen/logrus"
)
type fakeLogger struct {
}
func (l *fakeLogger) Format(e *logrus.Entry) ([]byte, error) {
return nil, nil
}
func main() {
currentAccessKey := [6]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
newAccessKey := [6]byte{3, 14, 15, 92, 65, 35}
sector := 1
block := 0
mySecret := "@~>f=Um[X{LRwA3}"
rfid, err := rf522.MakeRFID(0, 0, 1000000, 13, 11)
if err != nil {
logrus.Fatal(err)
}
data := waitRead(rfid, sector, block, currentAccessKey)
fmt.Printf("RFID sector %d, block %d : %v (str: %s)", sector, block, data, string(data))
conv := [16]byte{}
for i, v := range mySecret {
conv[i] = byte(v)
}
err = rfid.WriteBlock(byte(commands.PICC_AUTHENT1B), sector, block, conv, currentAccessKey[:])
if err != nil {
panic(err.Error())
}
err = rfid.WriteSectorTrail(commands.PICC_AUTHENT1A, sector, currentAccessKey, newAccessKey, &rf522.BlocksAccess{
B0: rf522.RAB_WB_IB_DAB,
B1: rf522.RB_WB_IN_DN,
B2: rf522.AnyKeyRWID,
B3: rf522.KeyA_RN_WN_BITS_RAB_WN_KeyB_RN_WN,
}, currentAccessKey[:])
if err != nil {
panic(err.Error())
}
data = waitRead(rfid, sector, block, newAccessKey)
fmt.Printf("RFID sector %d, block %d : %v (str: %s)", sector, block, data, string(data))
if mySecret != string(data) {
panic("Failed to update")
}
}
func waitRead(rfid *rf522.RFID, sector int, block int, key [6]byte) []byte {
logrus.SetFormatter(&fakeLogger{})
for {
data, err := rfid.ReadCard(byte(commands.PICC_AUTHENT1B), sector, block, key[:])
if err != nil {
continue
}
logrus.SetFormatter(&logrus.TextFormatter{})
return data
}
}