|
|
|
|
@ -123,6 +123,20 @@ func (r *Dev) SetAntennaGain(gain int) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadUID reads the card UID with IRQ event timeout.
|
|
|
|
|
//
|
|
|
|
|
// timeout the operation timeout
|
|
|
|
|
func (r *Dev) ReadUID(timeout time.Duration) (uid []byte, err error) {
|
|
|
|
|
r.beforeCall()
|
|
|
|
|
defer func() {
|
|
|
|
|
r.afterCall()
|
|
|
|
|
if err == nil {
|
|
|
|
|
err = r.LowLevel.StopCrypto()
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
return r.selectCard(timeout)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadCard reads the card sector/block with IRQ event timeout.
|
|
|
|
|
//
|
|
|
|
|
// timeout the operation timeout
|
|
|
|
|
@ -303,6 +317,35 @@ func (r *Dev) antiColl() ([]byte, error) {
|
|
|
|
|
return backData, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// antiColl2 performs additional anticollision check for UIDs with more than 4 bytes.
|
|
|
|
|
func (r *Dev) antiColl2() ([]byte, error) {
|
|
|
|
|
if err := r.LowLevel.DevWrite(commands.BitFramingReg, 0x00); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
serial := []byte{commands.PICC_ANTICOLL2, 0x20}
|
|
|
|
|
check := byte(0)
|
|
|
|
|
|
|
|
|
|
backData, _, err := r.LowLevel.CardWrite(commands.PCD_TRANSCEIVE, serial)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(backData) != 5 {
|
|
|
|
|
return nil, wrapf("Anticoll2 error, response is %d bytes-long, expected 5", len(backData))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := 0; i < 4; i++ {
|
|
|
|
|
check ^= backData[i]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if check != backData[4] {
|
|
|
|
|
return nil, wrapf("Anticoll2 error, check failed")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return backData, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// selectTag selects the FOB device by device UUID.
|
|
|
|
|
func (r *Dev) selectTag(serial []byte) (byte, error) {
|
|
|
|
|
dataBuf := make([]byte, len(serial)+2)
|
|
|
|
|
@ -355,6 +398,17 @@ func (r *Dev) selectCard(timeout time.Duration) ([]byte, error) {
|
|
|
|
|
if _, err := r.selectTag(uuid); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if uuid[0] == 0x88 { // Incomplete UID
|
|
|
|
|
// Get remaining bytes
|
|
|
|
|
uuidEnd, err := r.antiColl2()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uuid = uuid[1 : len(uuid)-1]
|
|
|
|
|
uuid = append(uuid, uuidEnd[:len(uuidEnd)-1]...)
|
|
|
|
|
}
|
|
|
|
|
return uuid, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|