Package org.nfctools.mf.ndef

Source Code of org.nfctools.mf.ndef.MfNdefWriter

/**
* Copyright 2011-2012 Adrian Stabiszewski, as@nfctools.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nfctools.mf.ndef;

import java.io.IOException;
import java.util.List;

import org.nfctools.mf.MfConstants;
import org.nfctools.mf.MfException;
import org.nfctools.mf.MfReaderWriter;
import org.nfctools.mf.block.TrailerBlock;
import org.nfctools.mf.card.MfCard;
import org.nfctools.mf.classic.Key;
import org.nfctools.mf.classic.KeyValue;
import org.nfctools.mf.mad.Application;
import org.nfctools.mf.mad.ApplicationDirectory;
import org.nfctools.mf.mad.MadUtils;
import org.nfctools.mf.tlv.NdefMessageTlv;
import org.nfctools.mf.tlv.TypeLengthValueWriter;
import org.nfctools.ndef.NdefMessageEncoder;
import org.nfctools.ndef.NdefWriter;
import org.nfctools.ndef.Record;
import org.nfctools.tags.TagOutputStream;
import org.nfctools.utils.NfcUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Deprecated
public class MfNdefWriter implements NdefWriter<MfCard> {

  private Logger log = LoggerFactory.getLogger(getClass());

  private MfReaderWriter readerWriter;
  private NdefMessageEncoder ndefMessageEncoder;
  private Key createKey = Key.A;
  private byte[] createKeyValue = MfConstants.TRANSPORT_KEY;
  private byte[] writeKeyValue = MfConstants.NDEF_KEY;
  private byte[] deleteKeyValue = MfConstants.NDEF_KEY;

  public MfNdefWriter(MfReaderWriter readerWriter, NdefMessageEncoder ndefMessageEncoder) {
    this.readerWriter = readerWriter;
    this.ndefMessageEncoder = ndefMessageEncoder;
  }

  /**
   * Sets the create key for the MAD sectors. If a mifare card does not have a MAD in sector 0 it is assumed that it
   * is in the transport configuration. In this case the writer will use the create key to write the MAD trailer.
   * Default is MfConstants.TRANSPORT_KEY.
   *
   * @param createKey
   */
  public void setCreateKey(Key createKey) {
    this.createKey = createKey;
  }

  /**
   * Sets the write key to protect the NDEF sectors. This is your secret key. The default is MfConstants.NDEF_KEY.
   *
   * @param writeKeyValue
   */
  public void setWriteKeyValue(byte[] writeKeyValue) {
    this.writeKeyValue = writeKeyValue;
  }

  /**
   * Sets the delete key to be able to delete any previous NDEF sectors. The default is MfConstants.NDEF_KEY.
   *
   * @param deleteKeyValue
   */
  public void setDeleteKeyValue(byte[] deleteKeyValue) {
    this.deleteKeyValue = deleteKeyValue;
  }

  @Override
  public void writeNdefMessage(MfCard card, List<Record> records) throws IOException {

    byte[] ndefData = ndefMessageEncoder.encode(records);

    writeNdefMessage(card, ndefData);
  }

  private void writeNdefMessage(MfCard card, byte[] ndefData) throws IOException, MfException {
    ApplicationDirectory applicationDirectory = null;

    if (MadUtils.hasApplicationDirectory(card, readerWriter))
      applicationDirectory = MadUtils.getApplicationDirectory(card, readerWriter, writeKeyValue);
    else
      applicationDirectory = MadUtils.createApplicationDirectory(card, readerWriter, createKey, createKeyValue,
          writeKeyValue);

    TrailerBlock trailerBlock = createNdefTrailerBlock();

    if (applicationDirectory.hasApplication(MfNdefConstants.NDEF_APP_ID)) {
      applicationDirectory.deleteApplication(MfNdefConstants.NDEF_APP_ID, deleteKeyValue, new TrailerBlock());
    }

    byte[] tlvWrappedNdefData = wrapNdefMessageWithTlv(ndefData, applicationDirectory.getMaxContinousSize());

    /*
     * The specs states that the TLV terminator can be left out if the message ends with the available space.
     * One might want to check if the available size on the card is one byte less than the tlv wrapped message. If
     * it is the case the TLV terminator could be removed.
     */
    Application application = applicationDirectory.createApplication(MfNdefConstants.NDEF_APP_ID,
        tlvWrappedNdefData.length, writeKeyValue, trailerBlock);

    if (log.isDebugEnabled())
      log.debug("Length: " + tlvWrappedNdefData.length + " [" + NfcUtils.convertBinToASCII(tlvWrappedNdefData)
          + "]");

    application.write(new KeyValue(Key.B, writeKeyValue), tlvWrappedNdefData);
  }

  private TrailerBlock createNdefTrailerBlock() throws MfException {
    TrailerBlock trailerBlock = new TrailerBlock();
    trailerBlock.setKey(Key.A, MfConstants.NDEF_KEY);
    trailerBlock.setKey(Key.B, writeKeyValue);
    trailerBlock.setAccessConditions(MfConstants.NDEF_READ_WRITE_ACCESS_CONDITIONS);
    trailerBlock.setGeneralPurposeByte(MfConstants.NDEF_GPB_V10_READ_WRITE);
    return trailerBlock;
  }

  private byte[] wrapNdefMessageWithTlv(byte[] ndefMessage, int maxSize) {
    TagOutputStream out = new TagOutputStream(maxSize);
    TypeLengthValueWriter writer = new TypeLengthValueWriter(out);
    writer.write(new NdefMessageTlv(ndefMessage));
    writer.close();

    return out.getBuffer();
  }
}
TOP

Related Classes of org.nfctools.mf.ndef.MfNdefWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.