利用PN532读取二代证UID

准备工作

芯片选择

NFC芯片,需要支持ISO14443 Type B协议,比如PN532

阅读ISO 14443

重点阅读如下内容:

  • 7.3.4.1 状态转换图
  • 7.3.5 ~ 7.3.7 REQB相关
  • 7.3.9 REQB的响应ATQB
  • 7.3.10 ATTRIB命令
  • 7.3.11 ATTRIB响应

libnfc

部署

参考官方:http://nfc-tools.org/index.php?title=Libnfc
Tips: 编译时请使用./configure --with-drivers=all --prefix=/usr --sysconfdir=/etc
含义如下:
--with-drivers=all 意思编译所有驱动
--prefix=/usr 安装目录
--sysconfdir=/etc 配置文件目录

使用USB-TTL方式连接

GND    <------>    GND
5V    <------>    VCC
TX    <------>    RX
RX    <------>    TX

配置Debug日志

有两种方式:

  • 在配置文件里设置日志级别
# cat /usr/local/etc/nfc/libnfc.conf
name = “Adafruit PN532 board via UART”
connstring = pn532_uart:/dev/ttyUSB0
allow_intrusive_scan = true
log_level = 3
  • 设置环境变量
    两种方式设置环境变量:
    <1>程序运行前加给变量赋值,比如
LIBNFC_LOG_LEVEL=3 ./examples/nfc-anticol -g

<2>程序内部利用setenv函数设置环境变量,比如

if (debug)
{
    setenv("LIBNFC_LOG_LEVEL", "3", 1);
}

添加读取UID逻辑

流程简述

根据网上查阅资料,读取步骤如下:

  1. 发送REQB
  2. 接受REQB的响应ATQB
  3. 发送ATTRIB
  4. 接受ATTRIB响应
  5. 发送读取Type B的UID命令
  6. 接受UID

PN532寄存器设置

网上查阅资料,自己试验,需要在libnfc/chips/pn53x.c文件的pn53x_reset_settings函数中加入:

    pn53x_write_register(pnd, PN53X_REG_CIU_Mode, 0xff, 0xff);
    pn53x_write_register(pnd, PN53X_REG_CIU_TxAuto, 0xff, 0x00);
    pn53x_write_register(pnd, PN53X_REG_CIU_TxMode, 0xff, 0x03);
    pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, 0xff, 0x03);
    pn53x_write_register(pnd, PN53X_REG_CIU_TypeB, 0xff, 0x03);
    pn53x_write_register(pnd, PN53X_REG_CIU_Demod, 0xff, 0x4d);
    pn53x_write_register(pnd, PN53X_REG_CIU_GsNOn, 0xff, 0xff);
    pn53x_write_register(pnd, PN53X_REG_CIU_CWGsP, 0xff, 0x3f);
    pn53x_write_register(pnd, PN53X_REG_CIU_ModGsP, 0xff, 0x18);
    pn53x_write_register(pnd, PN53X_REG_CIU_RxThreshold, 0xff, 0x4d);
    pn53x_write_register(pnd, PN53X_REG_CIU_ModWidth, 0xff, 0x68);
    pn53x_write_register(pnd, PN53X_REG_CIU_ManualRCV, 0xff, 0x10);

读取模块

具体利用libnfc实现相关逻辑,核心代码如下:

    uint8_t PUPI[4];

    uint8_t  REQB[5] = { 0x05, 0x00, 0x00 };
    iso14443b_crc_append(REQB, 3);
    transmit_bytes(REQB, 5); //发送REQB
    memcpy(PUPI, abtRx + 1, 4); //复制ATQB的PUIP

    printf("PUPI: ");
    print_hex(PUPI, 4);

    uint8_t Attrib[11] = { 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x01 };
    memcpy(Attrib + 1, PUPI, 4);
    iso14443b_crc_append(Attrib, 9);
    transmit_bytes(Attrib, 11); //发送ATTRIB

    uint8_t ReadGUID[7] = {0x00, 0x36, 0x00, 0x00, 0x08};
    iso14443b_crc_append(ReadGUID, 5);
    transmit_bytes(ReadGUID, 7); //发送读取UID命令

    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_SUCCESS);

读取UID

➜  libnfc git:(master) ✗ ./examples/nfc-anticol -g
NFC reader: pn532_uart:/dev/ttyUSB0 opened

Sent bits:     05  00  00  71  ff
Received bits: 50  00  00  00  00  d1  03  00  81  00  70  90  84  10
PUPI: 00  00  00  00
Sent bits:     1d  00  00  00  00  00  08  01  01  32  8d
Received bits: 01  f1  e1
Sent bits:     00  36  00  00  08  57  44
Received bits: 1x  xx  xx  xx  xx  xx  xx  xx  90  00  8a  45

参考资料

posted @ 2017-09-14 00:26  雨中尘埃  阅读(2398)  评论(0编辑  收藏  举报