/* * * * Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */ package com.sun.satsa.gsmapplet; import sim.toolkit.AccessSAT; import sim.toolkit.ToolkitInterface; import sim.toolkit.ToolkitException; import javacard.framework.AID; import javacard.framework.APDU; import javacard.framework.Util; import javacard.framework.JCSystem; /** * A class that implements the AccessSAT interface which * allows the toolkit classes to access the APDUBuffer * and do other functions on objects in the GSMApplet's context. */ public class AccessSATImpl implements AccessSAT { /** Maximum length of in and out buffers */ static final short MAX_BUFFER_LENGTH = (short)64; /** Maximum number of listeners allowed */ static final byte MAX_LISTENERS = (byte)16; /** * Size used by the GSM applet to send data when * responding to GET RESPONSE */ short outDataSize; /** Buffer that holds the data received from the terminal. */ public byte[] inBuffer; /** Buffer that holds the data to be sent to the terminal. */ public byte[] outBuffer; /** Buffer that holds the APDU data. */ private byte[] apduBuffer; /** Length of APDU buffer. */ private short apduBufferLength = 0; /** A list of listeners for EVENT_SMS_PP_DATA_DOWNLOAD. */ public ToolkitInterface[] tiList; /** * Constructor */ AccessSATImpl() { inBuffer = JCSystem.makeTransientByteArray(MAX_BUFFER_LENGTH, JCSystem.CLEAR_ON_DESELECT); outBuffer = JCSystem.makeTransientByteArray(MAX_BUFFER_LENGTH, JCSystem.CLEAR_ON_DESELECT); apduBuffer = JCSystem.makeTransientByteArray(MAX_BUFFER_LENGTH, JCSystem.CLEAR_ON_DESELECT); tiList = new ToolkitInterface[MAX_LISTENERS]; } /** * Resets the buffers and fields when a new envelope is received */ void resetBuffers() { Util.arrayFillNonAtomic(inBuffer, (short)0, MAX_BUFFER_LENGTH, (byte)0); Util.arrayFillNonAtomic(outBuffer, (short)0, MAX_BUFFER_LENGTH, (byte)0); outDataSize = (short)0; apduBufferLength = (short)0; } /** * Returns the APDUBuffer. * @return apdu buffer */ public byte[] getAPDUBuffer() { return apduBuffer; } /** * Sets the APDUBuffer. * @param buffer apdu buffer * @param length length of apdu buffer */ public void setAPDUBuffer(byte[] buffer, short length) { Util.arrayCopyNonAtomic(buffer, (short)0, apduBuffer, (short)0, length); Util.arrayCopyNonAtomic(buffer, (short)0, inBuffer, (short)0, length); apduBufferLength = length; } /** * Gets one byte from the APDUBuffer. * @param index Index of requested byte in the buffer * @return requested byte */ public byte getAPDUBufferByte(short index) { if (index >= MAX_BUFFER_LENGTH || index >= apduBufferLength) { return (byte)0; } else { return apduBuffer[index]; } } /** * Sets one byte from the APDUBuffer. * @param index Index of byte in the buffer * @param value The value to be set */ public void setAPDUBufferByte(short index, byte value) { if (index < MAX_BUFFER_LENGTH) { if (index > apduBufferLength) { apduBufferLength = index; } apduBuffer[index] = value; } } /** * Gets the length of the APDUBuffer. * @return requested length */ public short getAPDUBufferLength() { return apduBufferLength; } /** * Gets the maximum length of the APDUBuffer. * @return requested length */ public short getAPDUBufferMax() { return MAX_BUFFER_LENGTH; } /** * Sets the data in the out buffer. * @param length length of data */ public void setOutBufferData(short length) { byte[] buffer = apduBuffer; outDataSize = Util.arrayCopy(buffer, (short)0, outBuffer, outDataSize, length); // restore the bytes from the original command APDU in // the APDU buffer because the data recieved in the // envelope is suppose to be available while // in processToolkit method Util.arrayCopy(inBuffer, (short)0, buffer, (short)0, (short)length); } /** * Returns the length of Data that has been set in the out buffer. * @return length of data */ public short getOutDataLength() { return outDataSize; } /** * This method is called by GSMApplet to set the data in the APDU buffer * so that it can be sent to the terminal in response to a * GET RESPONSE APDU. */ public void setOutgoingAPDU() { // this will be called when there is data to be sent byte[] buffer = apduBuffer; Util.arrayCopy(outBuffer, (short)0, buffer, (short)0, outDataSize); } /** * Sets the event listener applet. * @param aid applet AID */ public void setEventListener(AID aid) { ToolkitInterface ti = (ToolkitInterface) JCSystem.getAppletShareableInterfaceObject(aid, (byte)0); if (ti == null) { ToolkitException.throwIt(ToolkitException.BAD_INPUT_PARAMETER); } // if listener hasn't already registered, register it for this event if (findListener(ti) == (byte)-1) { for (short i = 0; i < MAX_LISTENERS; i++) { if (tiList[i] == null) { tiList[i] = ti; break; } } } } /** * Removes the event listener from the list of listeners. * @param aid applet AID */ public void clearEventListener(AID aid) { ToolkitInterface ti = (ToolkitInterface) JCSystem.getAppletShareableInterfaceObject(aid, (byte)0); if (ti == null) { return; } byte index = findListener(ti); if (index != (byte)-1) { // remove listener tiList[index] = null; } } /** * Returns true if the applet corresponding to the AID passed to this * method is found in the list of listeners. * @param aid applet AID * @return true if the applet is a listener and false otherwise */ public boolean isEventListenerSet(AID aid) { ToolkitInterface ti = (ToolkitInterface) JCSystem.getAppletShareableInterfaceObject(aid, (byte)0); if (ti == null) { return false; } byte index = findListener(ti); if (index != (byte)-1) { return true; } return false; } /** * Finds a listener in the list of listener * @param ti toolkit interface * @return index in the listener table */ private byte findListener(ToolkitInterface ti) { for (byte i = 0; i < MAX_LISTENERS; i++) { if (tiList[i] != null) { if (tiList[i].equals(ti)) return i; } } return (byte)-1; } }