001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.satsa.gsmapplet;
028:
029: import sim.toolkit.AccessSAT;
030: import sim.toolkit.ToolkitInterface;
031: import sim.toolkit.ToolkitException;
032: import javacard.framework.AID;
033: import javacard.framework.APDU;
034: import javacard.framework.Util;
035: import javacard.framework.JCSystem;
036:
037: /**
038: * A class that implements the AccessSAT interface which
039: * allows the toolkit classes to access the APDUBuffer
040: * and do other functions on objects in the GSMApplet's context.
041: */
042: public class AccessSATImpl implements AccessSAT {
043: /** Maximum length of in and out buffers */
044: static final short MAX_BUFFER_LENGTH = (short) 64;
045:
046: /** Maximum number of listeners allowed */
047: static final byte MAX_LISTENERS = (byte) 16;
048:
049: /**
050: * Size used by the GSM applet to send data when
051: * responding to GET RESPONSE
052: */
053: short outDataSize;
054:
055: /** Buffer that holds the data received from the terminal. */
056: public byte[] inBuffer;
057:
058: /** Buffer that holds the data to be sent to the terminal. */
059: public byte[] outBuffer;
060:
061: /** Buffer that holds the APDU data. */
062: private byte[] apduBuffer;
063: /** Length of APDU buffer. */
064: private short apduBufferLength = 0;
065:
066: /** A list of listeners for EVENT_SMS_PP_DATA_DOWNLOAD. */
067: public ToolkitInterface[] tiList;
068:
069: /**
070: * Constructor
071: */
072: AccessSATImpl() {
073: inBuffer = JCSystem.makeTransientByteArray(MAX_BUFFER_LENGTH,
074: JCSystem.CLEAR_ON_DESELECT);
075: outBuffer = JCSystem.makeTransientByteArray(MAX_BUFFER_LENGTH,
076: JCSystem.CLEAR_ON_DESELECT);
077: apduBuffer = JCSystem.makeTransientByteArray(MAX_BUFFER_LENGTH,
078: JCSystem.CLEAR_ON_DESELECT);
079: tiList = new ToolkitInterface[MAX_LISTENERS];
080: }
081:
082: /**
083: * Resets the buffers and fields when a new envelope is received
084: */
085: void resetBuffers() {
086: Util.arrayFillNonAtomic(inBuffer, (short) 0, MAX_BUFFER_LENGTH,
087: (byte) 0);
088: Util.arrayFillNonAtomic(outBuffer, (short) 0,
089: MAX_BUFFER_LENGTH, (byte) 0);
090: outDataSize = (short) 0;
091: apduBufferLength = (short) 0;
092:
093: }
094:
095: /**
096: * Returns the APDUBuffer.
097: * @return apdu buffer
098: */
099: public byte[] getAPDUBuffer() {
100: return apduBuffer;
101: }
102:
103: /**
104: * Sets the APDUBuffer.
105: * @param buffer apdu buffer
106: * @param length length of apdu buffer
107: */
108: public void setAPDUBuffer(byte[] buffer, short length) {
109: Util.arrayCopyNonAtomic(buffer, (short) 0, apduBuffer,
110: (short) 0, length);
111: Util.arrayCopyNonAtomic(buffer, (short) 0, inBuffer, (short) 0,
112: length);
113: apduBufferLength = length;
114: }
115:
116: /**
117: * Gets one byte from the APDUBuffer.
118: * @param index Index of requested byte in the buffer
119: * @return requested byte
120: */
121: public byte getAPDUBufferByte(short index) {
122: if (index >= MAX_BUFFER_LENGTH || index >= apduBufferLength) {
123: return (byte) 0;
124: } else {
125: return apduBuffer[index];
126: }
127: }
128:
129: /**
130: * Sets one byte from the APDUBuffer.
131: * @param index Index of byte in the buffer
132: * @param value The value to be set
133: */
134: public void setAPDUBufferByte(short index, byte value) {
135: if (index < MAX_BUFFER_LENGTH) {
136: if (index > apduBufferLength) {
137: apduBufferLength = index;
138: }
139: apduBuffer[index] = value;
140: }
141: }
142:
143: /**
144: * Gets the length of the APDUBuffer.
145: * @return requested length
146: */
147: public short getAPDUBufferLength() {
148: return apduBufferLength;
149: }
150:
151: /**
152: * Gets the maximum length of the APDUBuffer.
153: * @return requested length
154: */
155: public short getAPDUBufferMax() {
156: return MAX_BUFFER_LENGTH;
157: }
158:
159: /**
160: * Sets the data in the out buffer.
161: * @param length length of data
162: */
163: public void setOutBufferData(short length) {
164: byte[] buffer = apduBuffer;
165: outDataSize = Util.arrayCopy(buffer, (short) 0, outBuffer,
166: outDataSize, length);
167: // restore the bytes from the original command APDU in
168: // the APDU buffer because the data recieved in the
169: // envelope is suppose to be available while
170: // in processToolkit method
171: Util.arrayCopy(inBuffer, (short) 0, buffer, (short) 0,
172: (short) length);
173: }
174:
175: /**
176: * Returns the length of Data that has been set in the out buffer.
177: * @return length of data
178: */
179: public short getOutDataLength() {
180: return outDataSize;
181: }
182:
183: /**
184: * This method is called by GSMApplet to set the data in the APDU buffer
185: * so that it can be sent to the terminal in response to a
186: * GET RESPONSE APDU.
187: */
188: public void setOutgoingAPDU() {
189: // this will be called when there is data to be sent
190: byte[] buffer = apduBuffer;
191: Util.arrayCopy(outBuffer, (short) 0, buffer, (short) 0,
192: outDataSize);
193: }
194:
195: /**
196: * Sets the event listener applet.
197: * @param aid applet AID
198: */
199: public void setEventListener(AID aid) {
200: ToolkitInterface ti = (ToolkitInterface) JCSystem
201: .getAppletShareableInterfaceObject(aid, (byte) 0);
202: if (ti == null) {
203: ToolkitException
204: .throwIt(ToolkitException.BAD_INPUT_PARAMETER);
205: }
206: // if listener hasn't already registered, register it for this event
207: if (findListener(ti) == (byte) -1) {
208: for (short i = 0; i < MAX_LISTENERS; i++) {
209: if (tiList[i] == null) {
210: tiList[i] = ti;
211: break;
212: }
213: }
214: }
215: }
216:
217: /**
218: * Removes the event listener from the list of listeners.
219: * @param aid applet AID
220: */
221: public void clearEventListener(AID aid) {
222: ToolkitInterface ti = (ToolkitInterface) JCSystem
223: .getAppletShareableInterfaceObject(aid, (byte) 0);
224: if (ti == null) {
225: return;
226: }
227: byte index = findListener(ti);
228: if (index != (byte) -1) {
229: // remove listener
230: tiList[index] = null;
231: }
232: }
233:
234: /**
235: * Returns true if the applet corresponding to the AID passed to this
236: * method is found in the list of listeners.
237: * @param aid applet AID
238: * @return true if the applet is a listener and false otherwise
239: */
240: public boolean isEventListenerSet(AID aid) {
241: ToolkitInterface ti = (ToolkitInterface) JCSystem
242: .getAppletShareableInterfaceObject(aid, (byte) 0);
243: if (ti == null) {
244: return false;
245: }
246: byte index = findListener(ti);
247: if (index != (byte) -1) {
248: return true;
249: }
250: return false;
251: }
252:
253: /**
254: * Finds a listener in the list of listener
255: * @param ti toolkit interface
256: * @return index in the listener table
257: */
258: private byte findListener(ToolkitInterface ti) {
259: for (byte i = 0; i < MAX_LISTENERS; i++) {
260: if (tiList[i] != null) {
261: if (tiList[i].equals(ti))
262: return i;
263: }
264: }
265: return (byte) -1;
266: }
267: }
|