/*
*
*
* Copyright 1990-2007 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;
}
}
|