Android Open Source - RejsekortReader R K F Card






From Project

Back to project page RejsekortReader.

License

The source code is released under:

GNU General Public License

If you think the Android project RejsekortReader listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package info.rejsekort.reader.rkf;
//  w w  w .j av  a2 s . c o  m
import info.rejsekort.reader.rkf.blocks.CMIBlock;
import info.rejsekort.reader.rkf.blocks.CommonTCSTBlock;
import info.rejsekort.reader.rkf.blocks.InterpretedBlock;
import info.rejsekort.reader.rkf.blocks.TCAS1Block;
import info.rejsekort.reader.rkf.blocks.TCCIBlock;
import info.rejsekort.reader.rkf.blocks.TCCPStaticBlock;
import info.rejsekort.reader.rkf.blocks.TCDBDynamicBlock;
import info.rejsekort.reader.rkf.blocks.TCDBStaticBlock;
import info.rejsekort.reader.rkf.blocks.TCDI1Block;
import info.rejsekort.reader.rkf.blocks.TCDI2Block;
import info.rejsekort.reader.rkf.blocks.TCDI3Block;
import info.rejsekort.reader.rkf.blocks.TCPUDynamicv4Block;
import info.rejsekort.reader.rkf.blocks.TCPUDynamicv6Block;
import info.rejsekort.reader.rkf.blocks.TCPUStaticBlock;
import info.rejsekort.reader.rkf.blocks.TCSTv4Block;
import info.rejsekort.reader.rkf.blocks.TCSTv5Block;
import info.rejsekort.reader.rkf.datatypes.DataType;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import android.nfc.tech.MifareClassic;
import android.util.Log;
import android.widget.Toast;

public class RKFCard {
  public static final String TAG = "RKFCard";

  MifareClassic mMFC;
  public CMIBlock mCMI;
  public TCCIBlock mTCCI;
  public TCDI1Block mTCDI1;
  public TCDI2Block mTCDI2;
  public TCDI3Block mTCDI3;
  public TCAS1Block mTCAS1;
  public TCPUStaticBlock mTCPUStatic;
  public InterpretedBlock mTCPUDynamic1;
  public InterpretedBlock mTCPUDynamic2;
  public ArrayList<TCELBlock_> mTCEL = new ArrayList<TCELBlock_>();
  public ArrayList<TCSTBlock> mTCST = new ArrayList<TCSTBlock>();
  public ArrayList<TCCPStaticBlock> mTCCP = new ArrayList<TCCPStaticBlock>();
  public TCDBStaticBlock mTCDBStatic;
  public ArrayList<TCDBDynamicBlock> mTCDBDynamic = new ArrayList<TCDBDynamicBlock>();

  
  public LinkedHashMap<String, InterpretedBlock> allBlocks = new LinkedHashMap<String, InterpretedBlock>();
  
  public static final byte[][] SECTORKEYS_A = {
    // sector 0
    DataType.hexStringToByteArray("fc00018778f7"),
    DataType.hexStringToByteArray("fc00018778f7"),
    DataType.hexStringToByteArray("fc00018778f7"),
    DataType.hexStringToByteArray("fc00018778f7"),
    DataType.hexStringToByteArray("fc00018778f7"),
    DataType.hexStringToByteArray("fc00018778f7"),
    DataType.hexStringToByteArray("fc00018778f7"),
    DataType.hexStringToByteArray("fc00018778f7"),
    // sector 8
    DataType.hexStringToByteArray("0297927c0f77"),
    DataType.hexStringToByteArray("0297927c0f77"),
    DataType.hexStringToByteArray("0297927c0f77"),
    DataType.hexStringToByteArray("0297927c0f77"),
    DataType.hexStringToByteArray("0297927c0f77"),
    //Sector 13
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    DataType.hexStringToByteArray("722bfcc5375f"),
    // sector 39
    DataType.hexStringToByteArray("fc00018778f7"),
  };
  
  protected RKFCard() {
  }
  
  public RKFCard(MifareClassic mfc) throws IOException {
    mMFC = mfc;
    parse();
  }

  public void parse() throws IOException {
    parseCMI();
    parseTCCI();
    parseTCDI();
    parseTCAS();
    parseTCPU();
    
    parseTCEL(3);
    parseTCEL(4);
    parseTCEL(5);
    parseTCEL(6);
    parseTCEL(7);
    
    parseTCST(36, 0);
    parseTCST(36, 6);
    parseTCST(36, 12);
    parseTCST(37, 3);
    parseTCST(37, 9);
    parseTCST(38, 0);
    parseTCST(38, 6);
    
    parseTCCP(13, 0, 13, 1);
    parseTCCP(13, 2, 14, 0);
    
    parseTCDB(15);
  }
  
  public byte[] getAccesKeyA(int sector) {
    return SECTORKEYS_A[sector];
  }
  
  public byte[] readBlock(int sector, int block) throws IOException {
    boolean auth = mMFC.authenticateSectorWithKeyA(sector, getAccesKeyA(sector));
    if (auth)
      return mMFC.readBlock(mMFC.sectorToBlock(sector) + block);
    else {
      Log.e(TAG, "Auth failed for sector " + sector);
      throw new IOException("Auth failed for sector " + sector);
    }
  }
  
  public byte[] readEntireCard() throws IOException {
    byte toret[] = new byte[mMFC.getSize()];
    int j = 0;
    
    for (int i = 0; i < mMFC.getBlockCount(); i++) {
      int sector = mMFC.blockToSector(i);
      boolean auth = mMFC.authenticateSectorWithKeyA(sector, getAccesKeyA(sector));
      if (auth) {
         byte block[] = mMFC.readBlock(i);
         for (byte b : block) {
           toret[j++] = b;
         }
      }
      else {
        Toast t = Toast.makeText(null, "Auth failed for block " + i + " (sector " + sector + ")", Toast.LENGTH_LONG);
        t.show();
      }
      
    }
    return toret;
  }
  
  void parseCMI() throws IOException {
    mCMI = new CMIBlock(readBlock(0, 0));
    allBlocks.put("CMI", mCMI);
  }
  void parseTCCI() throws IOException {
    mTCCI = new TCCIBlock(readBlock(0, 1));
    allBlocks.put("TCCI", mTCCI);
  }
  void parseTCAS() throws IOException {
    mTCAS1 = new TCAS1Block(readBlock(0, 2));
    allBlocks.put("TCAS1", mTCAS1);
  }
  
  void parseTCDI() throws IOException {
    mTCDI1 = new TCDI1Block(readBlock(1, 0));
    allBlocks.put("TCDI1", mTCDI1);
    mTCDI2 = new TCDI2Block(readBlock(1, 1));
    allBlocks.put("TCDI2", mTCDI2);
    mTCDI3 = new TCDI3Block(readBlock(1, 2));
    allBlocks.put("TCDI3", mTCDI3);
  }
  
  void parseTCPU() throws IOException {
    int[] sectors = {11, 9};
    
    for (int sector : sectors) {
      TCPUStaticBlock tcpustatic = new TCPUStaticBlock(readBlock(sector, 0));
      if (!tcpustatic.mIdentifier.mString.equals("85")) //not TCPU sector
        continue;
      if (tcpustatic.mVersionNumber.mInt == 6) {
        mTCPUStatic = tcpustatic;
        //Version 6, new
        allBlocks.put("TCPUStatic", mTCPUStatic);
        
        byte[] b1 = readBlock(sector, 2);
        byte[] b2 = readBlock(sector+1, 0);
        byte[] c = new byte[b1.length + b2.length];
        System.arraycopy(b1, 0, c, 0, b1.length);
        System.arraycopy(b2, 0, c, b1.length, b2.length);
        mTCPUDynamic1 = new TCPUDynamicv6Block(c);
        allBlocks.put("TCPUDynamic1", mTCPUDynamic1);
        
        b1 = readBlock(sector+1, 1);
        b2 = readBlock(sector+1, 2);
        c = new byte[b1.length + b2.length];
        System.arraycopy(b1, 0, c, 0, b1.length);
        System.arraycopy(b2, 0, c, b1.length, b2.length);
        mTCPUDynamic2 = new TCPUDynamicv6Block(c);
        allBlocks.put("TCPUDynamic2", mTCPUDynamic2);
      }
      else if (mTCPUStatic == null) { //only do this as fallback
        //Version 4, old
        mTCPUStatic = tcpustatic;
        allBlocks.put("TCPUStatic", mTCPUStatic);
        mTCPUDynamic1 = new TCPUDynamicv4Block(readBlock(sector, 1));
        allBlocks.put("TCPUDynamic1", mTCPUDynamic1);
        mTCPUDynamic2 = new TCPUDynamicv4Block(readBlock(sector, 2));
        allBlocks.put("TCPUDynamic2", mTCPUDynamic2);
      }
    }
  }
  
  void parseTCEL(int sector) throws IOException {
    for (int i = 0; i < 4; i++) {
      TCELBlock_ b = new TCELBlock_(readBlock(sector, i));
      mTCEL.add(b);
      allBlocks.put("TCEL" + mTCEL.size(), b);
    }
  }
  
  void parseTCST(int sector, int block0) throws IOException {
    byte[] b1 = readBlock(sector, block0);
    byte[] b2 = readBlock(sector, block0+1);
    byte[] b3 = readBlock(sector, block0+2);
    byte[] c = new byte[b1.length + b2.length + b3.length];
    System.arraycopy(b1, 0, c, 0, b1.length);
    System.arraycopy(b2, 0, c, b1.length, b2.length);
    System.arraycopy(b3, 0, c, b1.length+b2.length, b3.length);
    
    CommonTCSTBlock common = new CommonTCSTBlock(c);
    
    if (common.mVersionNumber.mInt == 5) {
      TCSTv5Block b = new TCSTv5Block(c);
      mTCST.add(b);
      allBlocks.put("TCST" + mTCST.size(), b);
    }
    else { //Assume version 4
      TCSTv4Block b = new TCSTv4Block(c);
      mTCST.add(b);
      allBlocks.put("TCST" + mTCST.size(), b);
    }
  }
  
  void parseTCCP(int sector0, int block0, int sector1, int block1) throws IOException {
    byte[] b1 = readBlock(sector0, block0);
    byte[] b2 = readBlock(sector1, block1);
    byte[] c = new byte[b1.length + b2.length];
    System.arraycopy(b1, 0, c, 0, b1.length);
    System.arraycopy(b2, 0, c, b1.length, b2.length);
    
    TCCPStaticBlock tccp = new TCCPStaticBlock(c);
    
    mTCCP.add(tccp);
    allBlocks.put("TCCP" + mTCCP.size(), tccp);
  }
  
  void parseTCDB(int sector) throws IOException {
    mTCDBStatic = new TCDBStaticBlock(readBlock(sector, 0));
    allBlocks.put("TCDBStatic", mTCDBStatic);
    
    {
      TCDBDynamicBlock b = new TCDBDynamicBlock(readBlock(sector, 1));
      mTCDBDynamic.add(b);
      allBlocks.put("TCDBDynamic" + mTCDBDynamic.size(), b);
    }
    
    {
      TCDBDynamicBlock b = new TCDBDynamicBlock(readBlock(sector, 2));
      mTCDBDynamic.add(b);
      allBlocks.put("TCDBDynamic" + mTCDBDynamic.size(), b);
    }
  }
  
  public int getCurSaldo() {
    if (mTCPUStatic.mVersionNumber.mInt == 6) {
      int ret = ((TCPUDynamicv6Block)mTCPUDynamic1).mValue.mAmount;
      if (((TCPUDynamicv6Block)mTCPUDynamic2).mPurseTransactionNumber.mInt > 
        ((TCPUDynamicv6Block)mTCPUDynamic1).mPurseTransactionNumber.mInt)
        ret = ((TCPUDynamicv6Block)mTCPUDynamic2).mValue.mAmount;
      return ret;
    }
    else { //Assume version 4
      int ret = ((TCPUDynamicv4Block)mTCPUDynamic1).mValue.mAmount;
      if (((TCPUDynamicv4Block)mTCPUDynamic2).mPurseTransactionNumber.mInt > 
        ((TCPUDynamicv4Block)mTCPUDynamic1).mPurseTransactionNumber.mInt)
        ret = ((TCPUDynamicv4Block)mTCPUDynamic2).mValue.mAmount;
      return ret;
    }
  }
  

}




Java Source Code List

info.rejsekort.reader.BlockDetailActivity.java
info.rejsekort.reader.BlockDetailFragment.java
info.rejsekort.reader.BlockListActivity.java
info.rejsekort.reader.BlockListFragment.java
info.rejsekort.reader.DisplayTravelDetailActivity.java
info.rejsekort.reader.DumpRaw.java
info.rejsekort.reader.MainActivity.java
info.rejsekort.reader.RejsekortReaderApp.java
info.rejsekort.reader.rkf.MockRKFCard.java
info.rejsekort.reader.rkf.RKFCard.java
info.rejsekort.reader.rkf.TCELBlock_.java
info.rejsekort.reader.rkf.TCSTBlock.java
info.rejsekort.reader.rkf.blocks.CMIBlock.java
info.rejsekort.reader.rkf.blocks.CommonTCSTBlock.java
info.rejsekort.reader.rkf.blocks.InterpretedBlock.java
info.rejsekort.reader.rkf.blocks.TCAS1Block.java
info.rejsekort.reader.rkf.blocks.TCCIBlock.java
info.rejsekort.reader.rkf.blocks.TCCPStaticBlock.java
info.rejsekort.reader.rkf.blocks.TCDBDynamicBlock.java
info.rejsekort.reader.rkf.blocks.TCDBStaticBlock.java
info.rejsekort.reader.rkf.blocks.TCDI1Block.java
info.rejsekort.reader.rkf.blocks.TCDI2Block.java
info.rejsekort.reader.rkf.blocks.TCDI3Block.java
info.rejsekort.reader.rkf.blocks.TCELBlock.java
info.rejsekort.reader.rkf.blocks.TCPUDynamicv4Block.java
info.rejsekort.reader.rkf.blocks.TCPUDynamicv6Block.java
info.rejsekort.reader.rkf.blocks.TCPUStaticBlock.java
info.rejsekort.reader.rkf.blocks.TCSTv4Block.java
info.rejsekort.reader.rkf.blocks.TCSTv5Block.java
info.rejsekort.reader.rkf.datatypes.BitArray.java
info.rejsekort.reader.rkf.datatypes.ByteString.java
info.rejsekort.reader.rkf.datatypes.DataType.java
info.rejsekort.reader.rkf.datatypes.DateCompact.java
info.rejsekort.reader.rkf.datatypes.DateMonth11.java
info.rejsekort.reader.rkf.datatypes.DateMonth8.java
info.rejsekort.reader.rkf.datatypes.DateTime.java
info.rejsekort.reader.rkf.datatypes.MoneyAmount24.java
info.rejsekort.reader.rkf.datatypes.RKFInteger.java
info.rejsekort.reader.rkf.datatypes.TimeCompact.java