Package org.nfctools.mf.classic

Source Code of org.nfctools.mf.classic.MfClassicNdefOperations

/**
* 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.classic;

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

import org.nfctools.NfcException;
import org.nfctools.api.TagInfo;
import org.nfctools.mf.MfConstants;
import org.nfctools.mf.block.TrailerBlock;
import org.nfctools.mf.mad.Application;
import org.nfctools.mf.mad.ApplicationDirectory;
import org.nfctools.mf.mad.MadKeyConfig;
import org.nfctools.mf.ndef.AbstractNdefOperations;
import org.nfctools.mf.tlv.NdefMessageTlv;
import org.nfctools.mf.tlv.TypeLengthValueReader;
import org.nfctools.mf.tlv.TypeLengthValueWriter;
import org.nfctools.ndef.Record;
import org.nfctools.tags.TagOutputStream;
import org.nfctools.utils.NfcUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MfClassicNdefOperations extends AbstractNdefOperations {

  private Logger log = LoggerFactory.getLogger(getClass());
  private MfClassicReaderWriter readerWriter;
  private byte[] writeKey = MfConstants.NDEF_KEY;

  public MfClassicNdefOperations(MfClassicReaderWriter readerWriter, TagInfo tagInfo, boolean formatted,
      boolean writeable) {
    super(tagInfo, formatted, writeable);
    this.readerWriter = readerWriter;
  }

  @Override
  public int getMaxSize() {
    assertFormatted();
    return getApplication().getAllocatedSize();
  }

  @Override
  public List<Record> readNdefMessage() {
    assertFormatted();
    if (lastReadRecords != null) {
      return lastReadRecords;
    }
    else {
      try {
        Application application = getApplication();
        // TODO create TagInputStream for better performance
        byte[] tlvWrappedNdefMessage = application.read(new KeyValue(Key.A, MfConstants.NDEF_KEY));
        if (log.isDebugEnabled())
          log.debug(NfcUtils.convertBinToASCII(tlvWrappedNdefMessage));
        TypeLengthValueReader reader = new TypeLengthValueReader(
            new ByteArrayInputStream(tlvWrappedNdefMessage));
        convertRecords(reader);
        return lastReadRecords;
      }
      catch (IOException e) {
        throw new NfcException(e);
      }
    }
  }

  private Application getApplication() {
    try {
      ApplicationDirectory applicationDirectory = readerWriter.getApplicationDirectory(new MadKeyConfig(Key.A,
          writeKey, writeKey));
      Application application = applicationDirectory.openApplication(MfConstants.NDEF_APP_ID);
      return application;
    }
    catch (IOException e) {
      throw new NfcException(e);
    }
  }

  @Override
  public void writeNdefMessage(Record... records) {
    assertWritable();
    assertFormatted();
    writeRecord(getApplication(), records);
  }

  @Override
  public void makeReadOnly() {
    assertFormatted();
    assertWritable();
    try {
      Application application = getApplication();
      application.getApplicationDirectory().makeReadOnly();
      application.makeReadOnly(new KeyValue(Key.B, writeKey));
      writable = false;
    }
    catch (IOException e) {
      throw new NfcException(e);
    }
  }

  @Override
  public void format(Record... records) {
    Application application = createNewApplication();
    writeRecord(application, records);
    formatted = true;
  }

  private Application createNewApplication() {
    try {
      ApplicationDirectory applicationDirectory = readerWriter.createApplicationDirectory(new MadKeyConfig(Key.A,
          MfConstants.TRANSPORT_KEY, writeKey));
      TrailerBlock readWriteTrailerBlock = ClassicHandler.createReadWriteDataTrailerBlock();
      readWriteTrailerBlock.setKey(Key.A, writeKey);
      readWriteTrailerBlock.setKey(Key.B, writeKey);
      Application application = applicationDirectory.createApplication(MfConstants.NDEF_APP_ID,
          applicationDirectory.getMaxContinousSize(), writeKey, readWriteTrailerBlock);
      return application;
    }
    catch (IOException e) {
      throw new NfcException(e);
    }
  }

  private void writeRecord(Application application, Record... records) {
    try {
      byte[] tlvWrappedNdefData = wrapNdefMessageWithTlv(convertRecordsToBytes(records),
          application.getAllocatedSize());
      application.write(new KeyValue(Key.B, writeKey), tlvWrappedNdefData);
    }
    catch (IOException e) {
      throw new NfcException(e);
    }
  }

  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.classic.MfClassicNdefOperations

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.