Commit bcfe3810 authored by qwelp's avatar qwelp
Browse files

use PC/SC golang wrapper instead of libnfc

parent 21e9a4fa
# nfcUID
nfcUID - terminal program for reading NFC tag UID by NFC reader and write it as keyboard output.
## Tech
Program used Go bindings to the PC/SC API.
https://github.com/ebfe/scard
It is works with ACS readers through their PC/SC driver. So driver should be installed first.
You can find driver in manufacturer site https://www.acs.com.hk/
## Supported readers
Program tested with readers:
- ACR122U
- ACR1281U-C1
- ACR1252U-M1
## Supported NFC tags
Program tested with tags:
- Mifare Classic
- Mifare Ultralight
- NTAG203
- NTAG213
- NTAG216
## Download/Install
1. Intall PC/SC driver for your reader (https://www.acs.com.hk/)
2. Download archive from release page and extract it. No installation needed.
3. Connect reader to PC.
4. In terminal windows launch program binary from extracted archive.
5. Open text field where you want to write tag UID (e.g. Notepad window, Excel cell etc)
6. Touch NFC tag to reader. Tag UID will be writted to current cursor postion in text field.
7. Release tag from reader.
## Build
To build your own binary just clone repo and use golang build command
```
go build
```
......@@ -2,70 +2,116 @@ package main
import (
"fmt"
"log"
"time"
"os"
"github.com/fuzxxl/nfc"
"github.com/ebfe/scard"
"github.com/taglme/string2keyboard"
)
func main() {
var devices []string
var err error
var reader nfc.Device
var information string
var nfcTarget *nfc.ISO14443aTarget
var target []nfc.Target
var uid string
res := nfc.Version()
fmt.Printf("Using libnfc version: %s\n", res)
devices, err = nfc.ListDevices()
if err != nil {
log.Fatal(err)
func errorExit(err error) {
fmt.Println(err)
os.Exit(1)
}
func waitUntilCardPresent(ctx *scard.Context, readers []string) (int, error) {
rs := make([]scard.ReaderState, len(readers))
for i := range rs {
rs[i].Reader = readers[i]
rs[i].CurrentState = scard.StateUnaware
}
for {
for i := range rs {
if rs[i].EventState&scard.StatePresent != 0 {
return i, nil
}
rs[i].CurrentState = rs[i].EventState
}
err := ctx.GetStatusChange(rs, -1)
if err != nil {
return -1, err
}
}
}
func waitUntilCardRelease(ctx *scard.Context, readers []string, index int) error {
rs := make([]scard.ReaderState, 1)
rs[0].Reader = readers[index]
rs[0].CurrentState = scard.StatePresent
for {
if rs[0].EventState&scard.StateEmpty != 0 {
return nil
}
rs[0].CurrentState = rs[0].EventState
err := ctx.GetStatusChange(rs, -1)
if err != nil {
return err
}
}
fmt.Printf("Found devices: \n %s", devices[0])
reader, err = nfc.Open(devices[0])
}
func main() {
// Establish a context
ctx, err := scard.EstablishContext()
if err != nil {
log.Fatal(err)
errorExit(err)
}
information, err = reader.Information()
defer ctx.Release()
// List available readers
readers, err := ctx.ListReaders()
if err != nil {
log.Fatal(err)
errorExit(err)
}
fmt.Printf("\nInformation about reader: %s\n", information)
modul := nfc.Modulation{nfc.ISO14443a, nfc.Nbr106}
for {
fmt.Printf("Found %d readers:\n", len(readers))
for i, reader := range readers {
fmt.Printf("[%d] %s\n", i, reader)
}
fmt.Printf("Wait for tag ...\n")
if len(readers) > 0 {
for {
fmt.Println("Waiting for a Card")
index, err := waitUntilCardPresent(ctx, readers)
if err != nil {
errorExit(err)
}
target, err = reader.InitiatorListPassiveTargets(modul)
// Connect to card
fmt.Println("Connecting to card in ", readers[index])
card, err := ctx.Connect(readers[index], scard.ShareExclusive, scard.ProtocolAny)
if err != nil {
log.Fatal(err)
errorExit(err)
}
if len(target) == 0 {
time.Sleep(100 * time.Millisecond)
} else {
break
defer card.Disconnect(scard.ResetCard)
var cmd = []byte{0xFF, 0xCA, 0x00, 0x00, 0x00}
rsp, err := card.Transmit(cmd)
if err != nil {
errorExit(err)
}
uid := string(rsp[0:7])
uidS := fmt.Sprintf("%x", uid)
fmt.Printf("Tag UID is: %s\n", uidS)
fmt.Printf("Writting as keyboard input...")
string2keyboard.KeyboardWrite(uidS)
fmt.Printf("Done.\n")
}
nfcTarget = target[0].(*nfc.ISO14443aTarget)
uid = string(nfcTarget.UID[:nfcTarget.UIDLen])
uidS := fmt.Sprintf("%x", uid)
fmt.Printf(" Tag UID is: %s\n", uidS)
fmt.Printf("Writting as keyboard input...")
string2keyboard.KeyboardWrite(uidS)
fmt.Printf("Done.\n")
card.Disconnect(scard.ResetCard)
}
//Wait while card will be released
fmt.Print("Waiting for card release...")
err = waitUntilCardRelease(ctx, readers, index)
fmt.Println("Card released.")
}
err = reader.Close()
if err != nil {
log.Fatal(err)
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment