// CHECKSTYLE:OFF
/*---------------------------------------------------------------------------
 * Copyright (C) 1999-2001 Maxim Integrated Products, All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL MAXIM INTEGRATED PRODUCTS BE LIABLE FOR ANY CLAIM, DAMAGES
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of Maxim Integrated Products
 * shall not be used except as stated in the Maxim Integrated Products
 * Branding Policy.
 *---------------------------------------------------------------------------
 */

package com.dalsemi.onewire.application.sha;

import com.dalsemi.onewire.OneWireException;
import com.dalsemi.onewire.adapter.OneWireIOException;

/**
 * <P>
 * Abstract super class for all SHA Transactions. Typical SHA transactions might
 * be something like an account debit application, a door access control system,
 * or a web-based authentication servlet. The <code>SHATransaction</code> super
 * class contains the bare minimum functionality necessary for the steps
 * involved in most SHA transaction applications.
 * </P>
 *
 * <P>
 * The first characteristic of a SHA Transaction is that it is tied to an
 * immutable <code>SHAiButtonCopr</code>, used for data signing and recreating
 * user authentication responses. The SHA Transaction guarantees an interface
 * for initializing account transaction data
 * (<code>setupTransactionData</code>), verifying that the transaction data has
 * not been tampered with (<code>verifyTransactionData</code>), performing the
 * transaction and updating the data (<code>executeTransaction</code>), and
 * validating a user with a challenge-response authentication protocol
 * (<code>verifyUser</code>).
 * </P>
 *
 * <P>
 * In addition, all transactions are characterized by certain parameters (i.e.
 * how much to debit from the user or what level of access is being requested
 * from the system). The interface for retrieving and setting these parameters
 * is provided through the generic <code>getParameter</code> and
 * <code>setParameter</code>.
 * </P>
 *
 * @see SHADebit
 * @see SHADebitUnsigned
 *
 * @version 1.00
 * @author SKH
 */
public abstract class SHATransaction {
	/** Turns on extra debugging for all SHATransactions */
	static final boolean DEBUG = false;

	static final int MAX_RETRY_CNT = 65536;

	static final java.util.Random rand = new java.util.Random();

	// **************************************************************** //
	// Error Constants
	// **************************************************************** //
	public static final int NO_ERROR = 0;
	public static final int SHA_FUNCTION_FAILED = -1;
	public static final int MATCH_SCRATCHPAD_FAILED = -2;
	public static final int COPR_WRITE_DATAPAGE_FAILED = -3;
	public static final int COPR_WRITE_SCRATCHPAD_FAILED = -4;
	public static final int COPR_BIND_SECRET_FAILED = -5;
	public static final int COPR_COMPUTE_CHALLENGE_FAILED = -6;
	public static final int COPROCESSOR_FAILURE = -6;
	public static final int USER_READ_AUTH_FAILED = -7;
	public static final int USER_WRITE_DATA_FAILED = -8;
	public static final int USER_BAD_ACCOUNT_DATA = -9;
	public static final int USER_DATA_NOT_UPDATED = -10;
	// **************************************************************** //

	/** The last error that occurred during this transaction */
	protected int lastError;

	/** The coprocessor used to complete this transaction */
	protected SHAiButtonCopr copr;

	/**
	 * <p>
	 * User applications should not instantiate this class without an instance of a
	 * coprocessor.
	 * </p>
	 */
	protected SHATransaction() {

	}

	/**
	 * <P>
	 * Creates a new SHATransaction, ensuring that reference to the coprocessor is
	 * saved and the errors are cleared.
	 * </P>
	 */
	protected SHATransaction(SHAiButtonCopr copr) {
		this.copr = copr;
		this.lastError = 0;
	}

	/**
	 * <P>
	 * Returns the error code for the last error in the transaction process.
	 * </P>
	 */
	public int getLastError() {
		return this.lastError;
	}

	/**
	 * <P>
	 * Returns the error code for the last error in the transaction process.
	 * </P>
	 */
	public int getLastCoprError() {
		return this.copr.getLastError();
	}

	/**
	 * <P>
	 * Setups initial transaction data on SHAiButtonUser. This step creates the
	 * account data file, signs it with the coprocessor, and writes it to the
	 * iButton.
	 * </P>
	 */
	public abstract boolean setupTransactionData(SHAiButtonUser user) throws OneWireException, OneWireIOException;

	/**
	 * <P>
	 * Verifies that SHAiButtonUser is a valid user of this service. This step
	 * writes a three byte challenge to the SHAiButtonUser before doing an
	 * authenticated read of the account data. The returned MAC is verified using
	 * the system authentication secret on the coprocessor. If the MAC matches that
	 * generated by the coprocessor, this function returns true.
	 * </P>
	 */
	public abstract boolean verifyUser(SHAiButtonUser user) throws OneWireException, OneWireIOException;

	/**
	 * <P>
	 * Verifies account data is valid for this service. The user's account data is
	 * recreated on the coprocessor and signed using the system signing secret. If
	 * the recreated signature matches the signature in the account data, the
	 * account data is valid.
	 * </P>
	 */
	public abstract boolean verifyTransactionData(SHAiButtonUser user) throws OneWireException, OneWireIOException;

	/**
	 * <P>
	 * Performs the transaction. For any given transaction type, this step would
	 * involve updating any necessary account data, signing the account data using
	 * the coprocessor's system signing secret, and writing the updated account data
	 * to the user iButton
	 * </P>
	 */
	public abstract boolean executeTransaction(SHAiButtonUser user, boolean verifySuccess)
			throws OneWireException, OneWireIOException;

	/**
	 * <P>
	 * Sets a particular parameter for this transaction. Parameters are specified in
	 * the class documentation for the specific type of transaction that is being
	 * performed.
	 * </P>
	 */
	public abstract boolean setParameter(int type, int param);

	/**
	 * <P>
	 * Retrieves the value of a particular parameter for this transaction.
	 * Parameters are specified in the class documentation for the specific type of
	 * transaction that is being performed.
	 * </P>
	 */
	public abstract int getParameter(int type);

	/**
	 * <P>
	 * Resets the value of all parameters for this transaction. Parameters are
	 * specified in the class documentation for the specific type of transaction
	 * that is being performed.
	 * </P>
	 */
	public abstract void resetParameters();
}
// CHECKSTYLE:ON
