2017-04-22 1 views
0

흰색 카드와 파란색 keyfob 트랜스 폰더가있는 이베이에서 "빨간색 일렉트로 우스 V3"키트를 얻었습니다. 그리고 패킷을 만들고 디코딩하는 C 프로그램을 작성했고 명령을 보내고 AC로 응답합니다 패킷, 그리고 버전과 상태를 읽을 수 있습니다. 저는 RFID 라이브러리를 사용하지 않고 있습니다. 저는 C 라이브러리를 사용하고 있고 그것을 이해하고 싶기 때문에 자신의 간단한 라이브러리를 만들고 있습니다. 저는 이것을 이해하고 싶어하는 사람들을 위해 간단한 단일 파일 데모를 공개하고 싶습니다. 어떤 arduino lib 또는 무엇 이건. 그게 내가 묻지 않는 모든 질문입니다.PN532가있는 패시브 NFC/RFID 장치는 어떻게 읽습니까?

정확한 명령은 수동 (비 동력) 트랜스 폰더의 존재를 스캔 보낼 무엇인가

그래서 여기에 내가 요구하고있는 질문입니다? 나는 그들이 어떤 종류인지는 확실치 않지만 키트와 함께 제공되며 아마도 ISO 14443/14443A입니다.

사실, 삼성 갤럭시 S4에서 태그를 사용했는데 ISO 14443-3A NXP MIFARE Classic 1K - 지원되지 않는다고합니다. 하지만 여전히 일련 번호가 표시됩니다.

지원되는 모든 카드 유형을 검색하는 정확한 명령은 무엇입니까?

명령을 보내려면 다음과 같은 함수를 사용하십시오. sendcmd ("0x4A 0x01 0x00"); (0xD4의 TFI가 자동으로 명령에 추가되고 전치사/len/lcs/체크섬이 모두 계산되어 처리됩니다.)

내 명령에 대해 ACK를 다시받을 수는 있지만 어느 것을 알 수 없는지 명령을 보내 카드를 스캔하거나 읽습니다.

PN532 카드 스캔 데이터를 다시 받아 볼 수 있다면 PN532 데이터 시트를 사용하여 구문 분석 할 수 있어야합니다.

없이 성공 데이터 시트에 표시된 관련 듯 모든 것을하려고하면, 매우

제시

답변

2

아 확인을 .. 감사합니다, 나는 13.56 CW /에 햄 라디오를 설정 LSB 거기 아무 것도 들리지 않았습니다. 그래서 RFRegulationTest 명령을 시도해 보았습니다. 그리고 그것은 모든 것을 열었습니다! 송신기를 켜고 다른 명령을 내릴 때까지 남겨 두는 테스트 명령 인 것처럼 보입니다. 그러나 필요에 따라 초기화됩니다.

그래서 여기가 카드에 대한 NXP NP532 스캔하기 위해 소요되는 명령입니다 : (115200bps를에 내가 사용 RS232를하지만, 다른 인터페이스와 유사해야합니다.)

당신은 그것을 보내

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0xFF 0x03 0xFD 0xD4 0x58 0x00 0xD4 

하고는 ACK를 얻을 수 있습니다 및 송신기가 키됩니다 × 00 × 00에 0xFF 0x00으로 0xFF를

그리고 송신기가 키 입력 할이 시점에서 0x00으로

.아마 100ms의 또는 뭔가 그렇게하자, 당신은 카드를 스캔을 시작할 수 있습니다

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0xFF 0x04 0xFC 0xD4 0x4A 0x02 0x00 0xE0 

다음 무선 송신기를 켜고 카드가 범위 때까지 카드를 스캔을 시작합니다 칩은, 다음이를 읽고 일련 번호와 같이 송신기를 종료하고 다음을 포함하는 패킷을 제공합니다 :

0x4B, 0x01/0x02 (1 또는 2 개의 카드가 감지되었는지 여부에 따라 다름) 일련 번호와 같이 카드에 대한 다양한 정보가 뒤에 오는 패킷을 제공합니다.

는 또한 다음과 같이 0xFF의 아래 번호로 시도의 수를 설정하여 0x4A는 0x02 0x00으로 명령을 주어 때 시도 할 것이다 시도의 최대 수를 설정할 수 있습니다

sendcmd("0x32 0x05 0xFF 0x01 0x10") 

하는 경우 당신이 읽기 명령 (× 00 0x4A는 0x02)가 두 번째 (은 0x10 번)의 일부분에 대한 노력 할게요을 줄 때 다음 포기하고 포함하는 패킷 전송 :

0x4B, 0x00 

카드가 발견 "의미 : 제로. "

모든 세부 사항은 데이터 시트를 참조하십시오. 내가 rf 테스트 명령을 실행할 때까지 송신기를 활성화하는 방법을 알지 못한다는 것을 제외하고는 알아야 할 모든 것을 알려줍니다.

어쨌든 원하는 경우 두 번째 명령을 몇 초 이상 계속 보내고 그 명령을 보낼 때마다 범위 내의 카드가 있는지 검색하고 알려주십시오!

0xFF로 다시 설정하면 카드가 감지 될 때까지 계속 시도하고 카드를 찾으면 카드 스캔 명령을 다시 보내면됩니다.

0xFF의 긴 문자열은 잠자기 상태가되어 전송 한 처음 몇 바이트를 놓치기 때문에 장치를 깨우는 것입니다.

나는 0xFF의 묶음으로 시작하여 무엇을 보내야하는지에 대한 예는 프리앰블, 길이 필드, 체크섬 및 계산 된 모든 것을 포함하는 전체 전체 패킷입니다. 카드를 스캔하도록 직접 보낼 수 있습니다.

초기 RF 테스트 명령과 재시도 설정 명령은 전원을 켤 때 한 번만 실행하면되고 필요하면 다시 읽기 명령을 계속 보냅니다. 버전으로

내 PN532 칩 보고서 자체를 : 1.6

여기에 내 작은 샘플 프로그램입니다 :

(내가 SO 게시물에서 들어 올려 RS232 초기화 부분은 - 그 쓴 누구에게 감사!)

(Linux 용) gcc nfc.c -o nfc.e로 컴파일

(모든 플랫폼으로 이식 할 수 있어야하며 직렬 포트를 처리하면됩니다. 나머지는 플랫폼에 독립적입니다.)

(이 기능은 카드를 스캔하고 일련 번호/NFCID를 반환하며 Mifare, ISO/IEC14443-3 유형 A 카드 (수동 모드에서는 106kbps) 만 반환합니다. 카드의 메모리를 실제로 읽고 쓰기를 원한다면 더 많은 코드를 작성해야하지만, 시작하기에 필요한 사항과 명령 구조가 작동하는 방법을 보여주고 패킷 전송 및 디코딩을위한 편리한 루틴을 제공합니다 .)

#include <errno.h> 
#include <fcntl.h> 
#include <string.h> 
#include <termios.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
int debug=0; 
int fd; 
void init_rs232(void); 
void sendpacket(unsigned char * payload, int len); 
void sendcmd(char * payload); 
int main(void) 
{ 
    printf("Welcome!\n"); 
    init_rs232(); 
    int waitfor; 
#define PACKET 1 
#define ACK 2 
    sendcmd("0x58 0x00");waitfor=ACK; //RFRegulationTest -- This command is used for radio regulation test. 
    int cstate=0; //Chat state, config state, whatever.. 
    int lc=0; 
    while(1) 
    { 
     lc++; //Send a scan command every second or so. 
     if(lc>1000) 
     { 
      lc=0; 
      sendcmd("0x4A 0x02 0x00"); //InListPassiveTarget -- The goal of this command is to detect as many targets (maximum MaxTg) as possible (max two) in passive mode. 
     } 

     if(cstate==1) //ACK's set the bottom bit in state, allowing it to go onto the next state. 
     { 
      sendcmd("0x02");waitfor=PACKET; //Read the version out of the PN532 chip. 
      cstate++; 
     } 
     if(cstate==3) //ACK's set the bottom bit in state, allowing it to go onto the next state. 
     { 
      sendcmd("0x04");waitfor=PACKET; //Get current status. 
      cstate++; 
     } 
     if(cstate==5) 
     { 
      waitfor=PACKET; 
      sendcmd("0x32 0x05 0xFF 0x01 0x10");//Max retries - last byte is for passive: 0=1 try, 1=2 tries, 254=255 tries, 0xFF=infinite retries. 
      //If last byte is 0xFF, then unit starts scanning for cards indefinitely. As soon as it detects a card, it stops scanning and returns info. 
      //If last byte is less than 0xFF, it tries scans and as soon as it finds a card returns info on it and stops trying, but 
      //if it never finds a card in the specified number of retries, it gives up and returns 0x4B, 0x00 (Cards found: Zero.) 
      cstate++; 
     } 
//Alternative way to send a new scan command each time the previous one gives up or finds a card: 
//  if(cstate==7) 
//  { 
//   waitfor=PACKET; 
//   sendcmd("0x4A 0x02 0x00");  //InListPassiveTarget 
//   cstate--; 
//  } 


     static unsigned char buffin [1000024]; 
     static unsigned char buf[1],bufo[1]; 
     int n; 
     static int bi=0; 
     unsigned char len,lcs,tfi,dcs; 

     bufo[0]=buf[0]; 
     n=read(fd,buf,sizeof(buf)); 
     if(n!=0) 
     { 
      if(n>0) 
      { 
       if(bi<1000000) 
       { 
        static int state=0; 

        if(state==0) //Waiting for preamble.. 
        { 
         if((bufo[0]==0)&&(buf[0]==0xFF)){state=10;} 
        } 
        else if(state==10) //Waiting for Len 
        { 
         len=buf[0]; 
         state=20; 
        } 
        else if(state==20) //Waiting for len checksum 
        { 
         if((len==0xFF)&&(buf[0]==0xFF)){printf("ERROR: BIG PACKET. Bye.\n");exit(-2);} 
         if((len==0x00)&&(buf[0]==0xFF)){state=21;} 
         else if((len==0xFF)&&(buf[0]==0x00)){state=21;} 
         else 
         { 
          lcs=buf[0]+len; 
          if(lcs){printf("ERROR: len checksum failed! 0x%02X\n",buf[0]);} 
          state=30; 
         } 
        } 
        else if(state==21) //Waiting for the 0x00 after ack/nack.. 
        { 
         state=0; 
         if(buf[0]==0x00) 
         { 
          if(bufo[0]==0xFF) 
          { 
           if(debug){printf("ACK!\n");} 
           if(waitfor==ACK){cstate=cstate|1;} 
          } 
          if(bufo[0]==0x00){printf("NACK!\n");} 

         }else{ 
          printf("ERROR: Invalid length, or ack/nack missing postamble...\n"); 
         } 
        } 
        else if(state==30) //Waiting for tfi.. 
        { 
         tfi=buf[0]; 
         //printf("tfi=0x%02X\n",tfi); 
         dcs=tfi; 
         bi=0; 
         state=40; 
        } 
        else if(state==40) //Saving bytes... 
        { 
         //printf("Saving payload byte 0x%02X\n",buf[0]); 
         buffin[bi++]=buf[0]; 
         dcs=dcs+buf[0]; 
         if(bi>=len){state=50;} 
        } 
        else if(state==50) //Calculating the checksum.. 
        { 
         state=0; 
         dcs=dcs+buf[0]; 
         if(dcs) 
         { 
          printf("ERROR: Data Checksum Failed! (0x%02X)\n",dcs); 
         }else{ 
          if(waitfor==PACKET){cstate=cstate|1;} 
          //printf("Good Packet: tfi=0x%02X, len=%d\n",tfi,len-1); 
          if(tfi==0xD5) 
          { 
           if(buffin[0]==0x03){printf("PN532 Version: %d.%d, features:%d\n",buffin[2],buffin[3],buffin[4]);} 
           if(buffin[0]==0x05) 
           { 

            printf("Status: Last Error:%d, Field:%d, Targets:%d, SAM Status:0x%02X\n",buffin[1],buffin[2],buffin[3],buffin[len-2]); 
            static char bitrates[255][10]={"106kbps","212kbps","424kbps"}; 
            static char modtypes[255][100]; 
            strcpy(modtypes[0x00],"Mifare, ISO/IEC14443-3 Type A, ISO/IEC14443-3 Type B, ISO/IEC18092 passive 106 kbps"); 
            strcpy(modtypes[0x10],"FeliCa, ISO/IEC18092 passive 212/424 kbps"); 
            strcpy(modtypes[0x01],"ISO/IEC18092 Active mode"); 
            strcpy(modtypes[0x02],"Innovision Jewel tag"); 
            if(buffin[3]==1){printf("Target %d: rx bps:%s, tx bps:%s, modulation type: %s.\n",buffin[4],bitrates[buffin[5]],bitrates[buffin[6]],modtypes[buffin[7]]);} 
            if(buffin[3]==2){printf("Target %d: rx bps:%s, tx bps:%s, modulation type: %s.\n",buffin[8],bitrates[buffin[9]],bitrates[buffin[10]],modtypes[buffin[11]]);} 
           } 
           if(buffin[0]==0x4B) 
           { 
            printf("FOUND %d CARDS!\n",buffin[1]); 
            //ONLY VALID FOR Mifare/ ISO type A 106KBPS: 
            int i,ii,iii; 
            i=0;ii=2; 
            while(i<buffin[1]) 
            { 
             printf("Target # %d:", buffin[ii++]); 
             printf("SENS_RES=0x%02X%02X, ",buffin[ii],buffin[ii+1]);ii++;ii++; 
             printf("SEL_RES=0x%02X, ",buffin[ii++]); 
             printf("NFCIDLength=%d, ",buffin[ii++]); 
             printf("NFCID="); 
             iii=0; 
             while(iii<buffin[ii-1]) 
             { 
              printf("%02X",buffin[ii+iii]); 
              iii++; 
              if(iii<buffin[ii-1]){printf(":");} 
             } 
             ii=ii+iii; 
             printf("\n"); 
             i++; 
            } 

           } 
           //Just a debugging thing for printing out the contents of valid packets. 
           //int i=0;while(i<(len-1)){printf("0x%02X, ",buffin[i++]);}printf("\n"); 
          } 
          else if(tfi==0x7F) 
          { 
           printf("Received error packet 0x7F with zero size.\n"); 
          }else{ 
           printf("ERROR: Got unknown %d byte packet with tfi=0x%02X!\n",len-1,tfi); 
          } 

         } 
        } 
        else 
        { 
         printf("Uhoh!\n"); 
        } 
        //printf("Got byte 0x%02X, now state is %d\n",(unsigned char)buf[0],state); 

       }else{ 
        printf("ERROR: bi=%d which is too big.. Starting over.\n",bi); 
        bi=0; 
       } 
      }else{ 
       printf("ERROR %d while reading serial port: %s\n",errno,strerror(errno)); 
       exit(-1); 
      } 
     } 

     usleep(1000); 

    } 



    return(0); 
} 




void init_rs232(void) 
{ 
    char *portname = "/dev/ttyUSB0"; 
    fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC); 
    if (fd < 0) 
    { 
      printf("error %d opening %s: %s", errno, portname, strerror (errno)); 
     exit(-1); 
    } 

     struct termios tty; 
     memset (&tty, 0, sizeof tty); 
     if (tcgetattr (fd, &tty) != 0) 
     { 
       printf("error %d from tcgetattr(%s)\n", errno,strerror(errno)); 
     exit(-1); 
     } 

     cfsetospeed (&tty, B115200); 
     cfsetispeed (&tty, B115200); 

     tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;  // 8-bit chars 
     // disable IGNBRK for mismatched speed tests; otherwise receive break 
     // as \000 chars 
     tty.c_iflag &= ~IGNBRK;   // disable break processing 
     tty.c_lflag = 0;    // no signaling chars, no echo, 
             // no canonical processing 
     tty.c_oflag = 0;    // no remapping, no delays 
     tty.c_cc[VMIN] = 0;   // read doesn't block 
     tty.c_cc[VTIME] = 0;   // 0.5 seconds read timeout 

     tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl 

     tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, 
             // enable reading 
     tty.c_cflag &= ~(PARENB | PARODD);  // shut off parity 
     tty.c_cflag |= 0; //This was parity 
     tty.c_cflag &= ~CSTOPB; 
     tty.c_cflag &= ~CRTSCTS; 

     if (tcsetattr (fd, TCSANOW, &tty) != 0) 
     { 
       printf("error %d from tcsetattr(%s)\n", errno,strerror(errno)); 
     exit(-1); 
     } 
} 


void sendpacket(unsigned char * payload, int len) 
{ 
    int tfi; 
    static unsigned char buffer[66000]; 
    int i,bo; 
    unsigned char lcs,dcs; 
    tfi=0xD4; 
    i=0; 
    bo=0; 
    while(i<=8){i++;buffer[bo++]=0xFF;} //Pre-padding.. 8-800 OK, 900 too much, 7 too little. Needs to be 0xFF I guess.. Probably wakes it up. 
    buffer[bo++]=0x00;   //Preamble. 
    buffer[bo++]=0xFF;    //Preamble. 
    len++; 
    lcs=-len;    //Length Checksum.. (yes...) 
    buffer[bo++]=len; 
    buffer[bo++]=lcs; 
    buffer[bo++]=tfi; 
    dcs=tfi; 
    i=0; 
    while((i<65900)&&(i<(len-1))) 
    { 
     buffer[bo]=payload[i]; 
     dcs=dcs+buffer[bo]; 
     bo++; 
     i++; 
    } 
    dcs=(-dcs); 
    buffer[bo++]=dcs; 
    write(fd,buffer,bo); 
    //printf("Sent %d bytes\n",bo); 
    //printf("Whole packet: "); 
    //i=0; 
    //while(i<bo) 
    //{ 
    // printf("0x%02X ",buffer[i]); 
    // i++; 
    //} 
    //printf("\n"); 
} 
void sendcmd(char * payload) //Accepts space separated argument list like "0xFF 0x0A 255 'USERID' 0 0" 
{    //strings are quoted in half quotes. half quotes inside a string are escaped \\' 
    int i,v;  //full quotes inside a string are escaped like \" 
    static unsigned char buffer[1024]; //back slashes inside a string are escaped like \\\\ . 
    static int bo;  //(The first escape or escape pair is for the C compiler, the second for this function: 
    bo=0;   // The actual contents of the string are just \' and \\) 
    i=0;   // Numeric formats supported are hex (0xNN), base ten (123), and octal (0377). 
    if(debug){printf("sendcmd: ");} 
    while(payload[i]) 
    { 
     if((payload[i]!='\'')&&(payload[i]!=' ')) 
     { 
      v=strtoul(&payload[i],NULL,0); 
      buffer[bo++]=v; 
      if(debug){printf("0x%02X, ",v);} 
      while(payload[i]>' '){i++;} 
     } 
     else if(payload[i]=='\'') 
     { 
      i++; 
      int keeprun; 
      keeprun=1; 
      while(keeprun) 
      { 
       if(payload[i]=='\\') 
       { 
        i++; 
       }else{ 
        if(payload[i]=='\''){keeprun=0;} 
       } 

       if((keeprun)&&(payload[i])) 
       { 
        buffer[bo++]=payload[i]; 
        if(debug){printf("%c",payload[i]);} 

       } 
       i++; 
      } 
      if(debug){printf(", ");} 

     } 
     else 
     { 
      i++; 
     } 
    } 
    if(debug){printf("\n");} 
    sendpacket(buffer,bo); 
} 
관련 문제