示例#1
0
  /**
   * Write all the blocks in a Tag to the Mifare tag.
   *
   * @param t
   * @throws IOException
   */
  public void write(Tag t) throws IOException {

    if (t.getSectorCount() > mKeys.getSectorCount()) throw new IOException("Too few keys");

    mTag.connect();

    int sectors = mTag.getSectorCount();

    try {

      for (int s = 0; s < sectors; ++s) {

        // Authenticate for each sector (try B key, then A key)
        if (!mTag.authenticateSectorWithKeyB(s, mKeys.getKeyB(s))
            && !mTag.authenticateSectorWithKeyA(s, mKeys.getKeyA(s)))
          throw new IOException("Auth error");

        // Write to tag. Skip block 0 and the trailer of each sector
        int blockOffset = mTag.sectorToBlock(s);
        int lastBlock = blockOffset + mTag.getBlockCountInSector(s);

        // Skip block 0
        blockOffset = blockOffset == 0 ? 1 : blockOffset;

        for (int b = blockOffset; b < lastBlock; ++b) {
          mTag.writeBlock(b, t.getBlock(b));
          if (mProgressListener != null)
            mProgressListener.publishProgress((100 * b) / t.getBlockCount());
        }
      }
    } finally {
      mTag.close();
    }
  }
示例#2
0
  private void resolveIntent(Intent intent) {
    String action = intent.getAction();
    toast("resolving intent");
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
      toast("RESOLVE THIS INTENT");
      Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
      receiveTab.append("\nResolve Intent for NDEF discovery");
    } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
      Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
      MifareClassic mfc = MifareClassic.get(tagFromIntent);
      byte[] data;
      receiveTab.append("\nNew tech tag received");
      try {
        mfc.connect();
        boolean auth = false;
        String cardData = null;
        int secCount = mfc.getSectorCount();
        int bCount = 0;
        int bIndex = 0;
        for (int j = 0; j < secCount; j++) {
          auth = mfc.authenticateSectorWithKeyA(j, MifareClassic.KEY_DEFAULT);
          if (auth) {
            bCount = mfc.getBlockCountInSector(j);
            bIndex = 0;
            for (int i = 0; i < bCount; i++) {
              bIndex = mfc.sectorToBlock(j);
              data = mfc.readBlock(bIndex);
              cardData = new String(data);
              receiveTab.append("\n" + cardData);
              bIndex++;
            }
          } else {
            Toast.makeText(this, "Auth failed", Toast.LENGTH_LONG).show();
          }
        }
      } catch (IOException ex) {
        Toast.makeText(this, "IO Error while attempting to read mifare", Toast.LENGTH_LONG).show();
      }
    } else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
      receiveTab.append("\nSome Tag found from card");
      Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

      receiveTab.append("\n" + tagFromIntent.toString());
      for (int k = 0; k < tagFromIntent.getTechList().length; k++) {
        receiveTab.append("\nTech List: " + tagFromIntent.getTechList()[k]);
        if (tagFromIntent.getTechList()[k].equals("android.nfc.tech.NfcA")) {
          // Run connection method
          parseNfcATag(tagFromIntent);
          // connectToNDEF(tagFromIntent);
          // parseMifareTag(tagFromIntent);
        } else if (tagFromIntent.getTechList()[k].equals("android.nfc.tech.Ndef")) {
          connectToNDEF(tagFromIntent);
          // receiveTab.append("\nRun connect to NDEF");
        }
      }
    }
  }
 /**
  * Set the mapping range for {@link #buildNextKeyMapPart()}.
  *
  * @param firstSector Index of the first sector of the key map.
  * @param lastSector Index of the last sector of the key map.
  * @return True if range parameters were correct. False otherwise.
  */
 public boolean setMappingRange(int firstSector, int lastSector) {
   if (firstSector >= 0 && lastSector < mMFC.getSectorCount() && firstSector <= lastSector) {
     mFirstSector = firstSector;
     mLastSector = lastSector;
     // Init. status of buildNextKeyMapPart to create a new key map.
     mKeyMapStatus = lastSector + 1;
     return true;
   }
   return false;
 }
示例#4
0
  /**
   * Test if all the keys in the KeyChain are valid, i.e. can be used for authenticating.
   *
   * @return true if all A and B keys can be used to authenticate, false otherwise.
   * @throws IOException
   */
  public boolean testKeys() throws IOException {

    // Tag and key sector count mismatch.
    // Need at least as many keys as there are sectors.
    if (mTag.getSectorCount() > mKeys.getSectorCount()) return false;

    mTag.connect();

    try {
      for (int i = 0; i < mTag.getSectorCount(); ++i) {
        if (!mTag.authenticateSectorWithKeyA(i, mKeys.getKeyA(i))
            || !mTag.authenticateSectorWithKeyB(i, mKeys.getKeyB(i))) {
          return false;
        }
      }
    } finally {
      mTag.close();
    }

    return true;
  }
示例#5
0
  /**
   * Read all blocks from the Mifare tag and return the data in a Tag object.
   *
   * @return A Tag object containing the data of the Mifare tag.
   * @throws IOException
   */
  public Tag read() throws IOException {

    int sectors = mTag.getSectorCount();
    Tag t = new Tag(TagType.getType(sectors));

    if (t.getSectorCount() > mKeys.getSectorCount()) throw new IOException("Too few keys");

    mTag.connect();

    try {

      for (int s = 0; s < sectors; ++s) {

        byte[] aKey = mKeys.getKeyA(s);
        byte[] bKey = mKeys.getKeyB(s);

        // Authenticate for each sector (try A key, then B key)
        if (!mTag.authenticateSectorWithKeyA(s, aKey) && !mTag.authenticateSectorWithKeyB(s, bKey))
          throw new IOException("Auth error");

        // Read every block of the sector
        int blockOffset = mTag.sectorToBlock(s);
        int lastBlock = blockOffset + mTag.getBlockCountInSector(s);
        for (int b = blockOffset; b < lastBlock; ++b) {
          byte[] readBuffer = mTag.readBlock(b);

          // Manually transfer key data to tag since it is usually not
          // readable
          if (b == lastBlock - 1) {
            for (int i = 0; i < Tag.KEY_SIZE; ++i) {
              readBuffer[i] = aKey[i];
              readBuffer[Tag.BLOCK_SIZE - Tag.KEY_SIZE + i] = bKey[i];
            }
          }

          t.setBlock(b, readBuffer);
          if (mProgressListener != null)
            mProgressListener.publishProgress((100 * b) / t.getBlockCount());
        }
      }

      return t;

    } finally {
      mTag.close();
    }
  }
 /**
  * Write a block of 16 byte data to tag.
  *
  * @param sectorIndex The sector to where the data should be written
  * @param blockIndex The block to where the data should be written
  * @param data 16 byte of data.
  * @param key The Mifare Classic key for the given sector.
  * @param useAsKeyB If true, key will be treated as key B for authentication.
  * @return The return codes are:<br>
  *     <ul>
  *       <li>0 - Everything went fine.
  *       <li>1 - Sector index is out of range.
  *       <li>2 - Block index is out of range.
  *       <li>3 - Data are not 16 byte.
  *       <li>4 - Authentication went wrong.
  *       <li>-1 - Error while writing to tag.
  *     </ul>
  *
  * @see #authenticate(int, byte[], boolean)
  */
 public int writeBlock(
     int sectorIndex, int blockIndex, byte[] data, byte[] key, boolean useAsKeyB) {
   if (mMFC.getSectorCount() - 1 < sectorIndex) {
     return 1;
   }
   if (mMFC.getBlockCountInSector(sectorIndex) - 1 < blockIndex) {
     return 2;
   }
   if (data.length != 16) {
     return 3;
   }
   if (!authenticate(sectorIndex, key, useAsKeyB)) {
     return 4;
   }
   // Write block.
   int block = mMFC.sectorToBlock(sectorIndex) + blockIndex;
   try {
     mMFC.writeBlock(block, data);
   } catch (IOException e) {
     Log.e(LOG_TAG, "Error while writing block to tag.", e);
     return -1;
   }
   return 0;
 }
 /**
  * Return the sector count of the Mifare Classic tag.
  *
  * @return The sector count of the current tag.
  */
 public int getSectorCount() {
   return mMFC.getSectorCount();
 }
示例#8
0
  private void resolveIntent(Intent intent) {
    // 1) Parse the intent and get the action that triggered this intent
    String action = intent.getAction();
    // 2) Check if it was triggered by a tag discovered interruption.
    if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {

      mydialog = ProgressDialog.show(ReadCardActivity.this, "loading", "loading");

      // 3) Get an instance of the TAG from the NfcAdapter
      Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
      // 4) Get an instance of the Mifare classic card from this TAG
      // intent
      MifareClassic mfc = MifareClassic.get(tagFromIntent);
      MifareClassCard mifareClassCard = null;

      try {
        // 5.1) Connect to card
        mfc.connect();

        // 5.2) and get the number of sectors this card has..and loop
        // thru these sectors
        int secCount = mfc.getSectorCount();
        mifareClassCard = new MifareClassCard(secCount);

        // init information
        String techtemp = "";
        for (String tech : mfc.getTag().getTechList()) {
          techtemp = techtemp + tech + "\n";
        }

        mifareClassCard.addValue("UID", Converter.getHexString(mfc.getTag().getId()));
        mifareClassCard.addValue("TechList", techtemp);
        // mifareClassCard.addValue("MemorySize", mfc.get);

        int bCount = 0;
        int bIndex = 0;
        for (int j = 0; j < secCount; j++) {
          boolean authKeyA = false;
          boolean authKeyB = false;

          MifareSector mifareSector = new MifareSector();
          mifareSector.sectorIndex = j;
          // 6.1) authenticate the sector

          for (String key : defaultKeys) {
            if (!authKeyA) {
              authKeyA = mfc.authenticateSectorWithKeyA(j, Converter.hexStringToByteArray(key));
              mifareSector.keyA = new MifareKey(Converter.hexStringToByteArray(key));
            }

            if (!authKeyB) {
              authKeyB = mfc.authenticateSectorWithKeyB(j, Converter.hexStringToByteArray(key));
              mifareSector.keyB = new MifareKey(Converter.hexStringToByteArray(key));
            }

            // 都满足则break
            if (authKeyA && authKeyB) {
              break;
            }
          }

          if ((authKeyA && authKeyB) || authKeyA || authKeyB) {
            mifareSector.authorized = true;

            // 6.2) In each sector - get the block count
            bCount = mfc.getBlockCountInSector(j);
            bCount = Math.min(bCount, MifareSector.BLOCKCOUNT);
            bIndex = mfc.sectorToBlock(j);

            // set access condition
            byte[] acdata = mfc.readBlock(bIndex + 3);
            String hexString = Converter.getHexString(acdata, 16);
            mifareSector.accessCondition = hexString.substring(12, 20);

            for (int i = 0; i < bCount; i++) {

              // 6.3) Read the block
              byte[] data = mfc.readBlock(bIndex);
              // System.out.println(Converter.getHexString(data, 16));
              MifareBlock mifareBlock = new MifareBlock(mifareSector);
              mifareBlock.setData(data);
              mifareBlock.setIndex(bIndex);
              // 7) Convert the data into a string from Hex
              // format.

              bIndex++;
              mifareSector.blocks[i] = mifareBlock;
            }
            mifareClassCard.setSector(mifareSector.sectorIndex, mifareSector);
          } else { // Authentication failed - Handle it
            mifareSector.authorized = false;
          }
        }
        this.mydialog.dismiss();
        mfc.close();
        Intent dataIntent = new Intent(this, ViewCardActivity.class);
        Bundle bundle = new Bundle();
        bundle.putSerializable("mifare", mifareClassCard);
        dataIntent.putExtras(bundle);
        this.startActivityForResult(dataIntent, 0);
        this.finish();
      } catch (IOException e) {
        Log.e(TAG, e.getLocalizedMessage());
        showAlert(3);
        this.mydialog.dismiss();
      } finally {

        if (mifareClassCard != null) {
          // mifareClassCard.debugPrint();
        }
      }
    } // End of IF
  } // End of method