2017-04-22 1 views
0

白いカードと青いキーフォブのトランスポンダーを使ってeBayの赤い「ELECHOUSE V3」キットを手に入れました。パケットを作成してデコードするCプログラムを書いたので、コマンドを送信してACで応答しますパケット、私はバージョンとステータスを読むことができます。私はRFIDライブラリを使用していません。単純なCライブラリを使っています。私はそれを理解したいので、実際に使っているだけではなく、理解したい人のためのシンプルな単一ファイルデモンストレーションをリリースしたいと思います。いくつかのarduinoのlibまたは何でも。それは私が求めていないすべての質問です。PN532でパッシブNFC/RFIDユニットを読み取るにはどうすればよいですか?

正確なコマンドは、受動的な(非パワード)トランスポンダの存在をスキャンするために送信するためにどのようなものです:

だからここに私が求めています質問ですね?私は彼らがどのような種類であるかは分かりませんが、キットに付属していて、おそらくISO 14443/14443Aです。

実際、私はSamsung Galaxy S4でタグを試しましたが、ISO 14443-3A NXP MIFARE Classic 1K - サポートされていないと言います。しかし、それはまだ彼らのためのシリアル番号を示しています。

サポートされているすべてのカードタイプをスキャンする正確なコマンドは何ですか?

コマンドを送信するには、次のような関数を使用します。 sendcmd( "0x4A 0x01 0x00"); (コマンドに0xD4のTFIが自動的に追加され、プリアンブル/ len/lcs /チェックサムがすべて計算されて処理されます)

私のコマンドではACKを返しますが、カードをスキャンしたり、読み取ったりするためのコマンドです。

私がPN532データシートを使用して解析することができるはずです。

はOKああ..なしの成功とデータシートに示された関連見えたすべてのものを試した後、私はそこに13.56MHzのCW/LSBとする上でアマチュア無線を回し

ジェシー

答えて

2

、どうもありがとうございました私はRFRegulationTestコマンドを試してみましたが、それはすべてをロック解除しました!あなたが別のコマンドを発行するまで送信機をオンにし、それを残すテストコマンドと思われます...しかし、それは必要に応じて何かを初期化します!だからここ

が、それはカードのNXP NP532スキャンを作るのにかかるコマンドです:(。私は115200bpsでRS232を使用していますが、他のインターフェイスについても同様でなければなりません)

あなたはそれに送る:

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

、あなたはACKと送信機が上のキーになる得るだろう: は0x00 0x00から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") 

、その場合にはあなたがリードコマンド(0x00から0x4A 0x02の)、第2(0x10の回)の割合のために頑張りますを与えるときにあきらめ含むパケットの送信:

0x4B, 0x00 

カードが見つかった「とはゼロに。 "

は、すべての詳細については、データシートを参照してください、それは私がRFテストコマンドを実行するまで、私は送信機を有効にする方法を見つけ出すことができなかったんを除いて、あなたが知る必要があるすべてを教えてくれません。

とにかく、2番目のコマンドを何度も何度も何度も何度も送信し続けます。そのコマンドを送信するたびに、範囲内にカードがあるかどうかをスキャンして通知します。

または、再試行回数を0xFFに設定すると、カードが検出されるまで永遠に試行されます。カードが検出されると、scan-for-cardコマンドを再送信するだけです。それはスリープ状態になると、あなたが送る最初の数バイトを逃すので

0xFFでの長い文字列は、単にデバイスをウェイクアップすることです。 0xFFの年代の束で始まる、私はそれを送信するかの与える

例はプリアンブル、長さフィールド、チェックサム、すべて計算を含む全パケット全体、です。それらを直接送信してカードをスキャンすることができます。

初期RFテストコマンドと再試行セットコマンドは、電源投入時に一度だけ実行する必要があります。その後、必要に応じてリードコマンドを再送信してください。バージョンとして

マイPN532チップレポート自体を:1.6

ここに私の小さなサンプルプログラムです:

(私はSOのポストから持ち上げRS232の初期化部分が - それを書いた誰に感謝!)

(いずれのプラットフォームにも移植できるはずですが、シリアルポートを扱うだけで、残りはプラットフォームに依存しません)

(また、これは単に受動モードで106kbpsでカードをスキャンし、シリアル番号/ NFCIDを返し、そして唯一のMifare、ISO/IEC14443-3タイプAカードのことに注意。実際にカード上のメモリに読み書きをしたい場合は、より多くのコードを書く必要がありますが、これは少なくとも開始するために必要なこととコマンド構造の仕組みを示し、パケットの送信と復号に便利なルーチンを提供します。)

#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); 
} 
関連する問題