Package org.nfctools.spi.tama.response

Source Code of org.nfctools.spi.tama.response.TamaResponseDecoder

/**
* 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.spi.tama.response;

import java.util.ArrayList;
import java.util.List;

import org.nfctools.spi.tama.TamaException;
import org.nfctools.spi.tama.TamaUtils;
import org.nfctools.spi.tama.response.GetGeneralStatusResp.Target;
import org.nfctools.utils.NfcUtils;

public class TamaResponseDecoder {

  @SuppressWarnings("unchecked")
  public <T> T decodeMessage(byte[] message) throws TamaException {
    if (message[0] == (byte)0xD5) {
      byte[] payload = new byte[message.length - 2];
      System.arraycopy(message, 2, payload, 0, payload.length);
      int responseCode = byteAsInt(message[1]);
      switch (responseCode) {
        case 0x03:
          return (T)createGetFirmwareVersionResp(payload);
        case 0x05:
          return (T)createGetGeneralStatusResp(payload);
        case 0x41:
          return (T)createDataExchangeResp(payload);
        case 0x57:
          return (T)createJumpForDepResp(payload);
        case 0x8D:
          return (T)createInitTamaTargetResp(payload);
        case 0x87:
          return (T)createGetDepDataResp(payload);
        case 0x45: // inDeselect
        case 0x53: // inRelease
        case 0x55: // inSelect
        case 0x8F: // tgSetDEPData
        case 0x95: // tgSetMetaDEPData
        case 0x93: // tgSetGeneralBytes
        case 0x91: // tgResponseToInitiator
          return (T)handleStatusCode(payload);
        case 0x13: // setParameters
        case 0x33: // rfCommunication
          return (T)Integer.valueOf(0);
        case 0x4b:
          return (T)createInListPassiveTargetResponse(payload);
      }
      throw new TamaException("unknown response " + responseCode);
    }
    else {
      throw new TamaException("Frame identifier (0xD5) expected, got [" + NfcUtils.convertBinToASCII(message)
          + "]");
    }
  }

  private InListPassiveTargetResp createInListPassiveTargetResponse(byte[] payload) {
    byte[] targetData = new byte[payload.length - 1];
    System.arraycopy(payload, 1, targetData, 0, targetData.length);
    return new InListPassiveTargetResp(payload[0], targetData);
  }

  private static int byteAsInt(byte b) {
    return b & 0xff;
  }

  private Integer handleStatusCode(byte[] payload) throws TamaException {
    int status = byteAsInt(payload[0]);
    TamaUtils.handleStatusCode(status);
    return Integer.valueOf(status);
  }

  private DataExchangeResp createDataExchangeResp(byte[] payload) throws TamaException {
    int statusByte = byteAsInt(payload[0]);
    handleStatusCode(payload);
    if (TamaUtils.isNADPresent(statusByte)) {
      // TODO add NAD handler
      throw new IllegalStateException("NAD in payload not supported yet");
    }
    byte[] data = new byte[payload.length - 1];
    System.arraycopy(payload, 1, data, 0, payload.length - 1);
    return new DataExchangeResp(TamaUtils.isMoreInformation(statusByte), data);
  }

  private JumpForDepResp createJumpForDepResp(byte[] payload) throws TamaException {
    handleStatusCode(payload);
    int targetId = byteAsInt(payload[1]);
    byte[] nfcId = new byte[10];
    System.arraycopy(payload, 2, nfcId, 0, nfcId.length);
    byte[] generalBytes = new byte[payload.length - 17];
    System.arraycopy(payload, 17, generalBytes, 0, generalBytes.length);
    return new JumpForDepResp(targetId, nfcId, byteAsInt(payload[12]), byteAsInt(payload[13]),
        byteAsInt(payload[14]), byteAsInt(payload[15]), byteAsInt(payload[16]), generalBytes);
  }

  private InitTamaTargetResp createInitTamaTargetResp(byte[] payload) {
    int mode = byteAsInt(payload[0]);
    byte[] initiatorCommand = new byte[payload.length - 1];
    System.arraycopy(payload, 1, initiatorCommand, 0, payload.length - 1);
    return new InitTamaTargetResp(mode, initiatorCommand);
  }

  private GetDepDataResp createGetDepDataResp(byte[] payload) throws TamaException {
    int statusByte = byteAsInt(payload[0]);
    handleStatusCode(payload);
    if (TamaUtils.isNADPresent(statusByte)) {
      // TODO add NAD handler
      throw new IllegalStateException("NAD in payload not supported yet");
    }
    byte[] dataIn = new byte[payload.length - 1];
    System.arraycopy(payload, 1, dataIn, 0, payload.length - 1);
    return new GetDepDataResp(TamaUtils.isMoreInformation(statusByte), dataIn);
  }

  private GetFirmwareVersionResp createGetFirmwareVersionResp(byte[] payload) {
    if (payload.length == 2) // PN531
      return new GetFirmwareVersionResp(byteAsInt(payload[0]), byteAsInt(payload[1]));
    else if (payload.length == 4) //PN532/PN533
      return new GetFirmwareVersionResp(byteAsInt(payload[0]), byteAsInt(payload[1]), byteAsInt(payload[2]),
          byteAsInt(payload[3]));
    else
      throw new RuntimeException("Cannot handle payload with length: " + payload.length);
  }

  private GetGeneralStatusResp createGetGeneralStatusResp(byte[] payload) {
    int lastError = byteAsInt(payload[0]);
    boolean externalRfDetected = payload[1] == 0x01;
    int numberOfTargets = byteAsInt(payload[2]);
    List<Target> targets = new ArrayList<GetGeneralStatusResp.Target>(2);
    for (int x = 0; x < numberOfTargets; x++) {
      targets.add(new Target(payload[3 + (x * 4)], payload[3 + (x * 4) + 1], payload[3 + (x * 4) + 2],
          payload[3 + (x * 4) + 3]));
    }
    int samStatus = byteAsInt(payload[3 + (4 * numberOfTargets)]);
    return new GetGeneralStatusResp(lastError, externalRfDetected, numberOfTargets, samStatus, targets);
  }
}
TOP

Related Classes of org.nfctools.spi.tama.response.TamaResponseDecoder

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.