• Android NFC近场通信03----读写MifareClassic卡


                                           Android NFC近场通信02----读写MifareClassic卡

    一.MifareClassic卡 相关

    一般来说,给予MifareClassic的射频卡,一般内存大小有3种:

    1K: 16个分区(sector)。每一个分区4个块(block)。每一个块(block) 16个byte数据

    2K: 32个分区,每一个分区4个块(block),每一个块(block) 16个byte数据

    4K:64个分区,每一个分区4个块(block)。每一个块(block) 16个byte数据

    对于全部基于MifareClassic的卡来说,每一个区最后一个块叫Trailer,16个byte, 主要来存放读写该区的key,能够有A,B两个KEY,每一个key长6byte,默认的key通常是FF 或 0。最后一个块的内存结构例如以下:

    Block 0  Data 16bytes
    Block 1  Data 16 bytes
    Block 2  Data 16 bytes
    Block 3  Trailer 16 bytes
    Trailer:
    Key A: 6 bytes
    Access Conditions: 4 bytes
    Key B: 6 bytes

    M1卡分为16个扇区,每一个扇区由4块(块0、块1、块2、块3)组成。(我们也将16个扇区的64个块按绝对地址编号为0~63。)存贮结构如右表所看到的


    0

    0

    数据块

    0

    1

    数据块

    1

    2

    数据块

    2

    3

    passwordA  存取控制    passwordB

    数据块

    3

    1

    0

    数据块

    4

    1

    数据块

    5

    2

    数据块

    6

    3

    passwordA  存取控制    passwordB

    数据块

    7


     

    15

    0

    数据块

    60

    1

    数据块

    61

    2

    数据块

    62

    3

    passwordA  存取控制    passwordB

    数据块

    63


    0扇区的0(即绝对地址0块),它用于存放厂商代码。已经固化。不可更改。

    每一个扇区的块0、块1、块2为数据块。可用于存贮数据。

    每一个扇区的块3为控制块,包含了passwordA、存取控制、passwordB。

    详细结构例如以下:

    A1A2 A3 A4 A5               FF 07 8069               B0 B1 B2 B3 B4 B5

    passwordA6字节)          存取控制(4字节)          passwordB6字节)  

    每一个扇区的password和存取控制都是独立的,能够依据实际须要设定各自的password及存取控制;

    存取控制为4个字节,共32位。扇区中的每一个块(包含数据块和控制块)的存取条件是由password和存取控制共同决定的。
    工作原理:

    读写器向M1卡发一组固定频率的电磁波,卡片内有一个LC串联谐振电路。其频率与讯写器发射的频率同样,在电磁波的激励下,LC谐振电路产生共振。从而使电容内有了电荷,在这个电容的还有一端。接有一个单向导通的电子泵,将电容内的电荷送到还有一个电容内储存,当所积累的电荷达到2V时。此电容可做为电源为其他电路提供工作电压,将卡内数据发射出去或接取读写器的数据。

    二.读取数据 

    //tag 就是在上一篇中onNewIntent中获取的tag
    MifareClassic mc = MifareClassic.get(tag);
            short startAddress = 0;
            short endAddress = 5;
    
            byte[] data = new byte[(endAddress - startAddress + 1 ) * ByteCountPerBlock];
            
            try {            
                mc.connect();for (short i = startAddress; i <= endAddress; i++ ,time++) {
                    boolean auth = false;
                    short sectorAddress = getSectorAddress(i);
                    auth = mc.authenticateSectorWithKeyA(sectorAddress, MifareClassic.KEY_DEFAULT);
                    if (auth){
                        
                        //the last block of the sector is used for KeyA and KeyB cannot be overwritted
                        short readAddress = (short)(sectorAddress == 0 ? i : i + sectorAddress);
                        
                        byte[] response = mc.readBlock(readAddress);
                        CombineByteArray(data, response, time * ByteCountPerBlock);
                    }
                    else{
                        throw new NfcException(NfcErrorCode.TemporaryError,
                                "Authorization Error.");
                    }
                }
    
                mc.close();
                
            }
            catch (NfcException ne) {
                throw ne;
            }
            catch (IOException e) {
                throw new NfcException(NfcErrorCode.TemporaryError,
                        "Get response, what it is not successfully.", e);
            }
            finally
            {
                try {
                    mc.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    三.写数据 

    //tag 就是在上一篇中onNewIntent中获取的tag
    MifareClassic mc = MifareClassic.get(tag);
    
                try {
                    mc.connect();
                    boolean auth = false;
                    short sectorAddress = 0
                    auth = mc.authenticateSectorWithKeyA(sectorAddress,
                            MifareClassic.KEY_DEFAULT);
                    if (auth) {
                        //the last block of the sector is used for KeyA and KeyB cannot be overwritted
                        
                        mc.writeBlock(readAddress, dataTemp);
    
                        mc.close();
                    } 
                }finally
                {
                    try {
                        mc.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

    附:NFC 论坛 http://www.nfcchina.org/forum.php

  • 相关阅读:
    第七章LED将为我闪烁:控制发光二极管
    第六章第一个Linux驱动程序:统计单词个数
    搭s3c6410开发板的测试环境读后感
    第四章源代码的下载和编译
    第三章Git使用入门(读后感)
    第二章:搭建Android开发环境(读后感)
    第一章:Android系统移植与驱动开发概述(读后感)
    函数和代码复用
    python的基本数据类型
    Python的语法元素
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6724117.html
Copyright © 2020-2023  润新知