Methods Summary |
---|
public static void | checkSlotNumber(int slot)Verifies that slot number is correct. Invokes init method
if necessary.
try {
init();
} catch (IOException e) {
throw new ConnectionNotFoundException(
"Invalid configuration");
}
if (slot < 0 || slot >= getSlotCount()) {
throw new ConnectionNotFoundException(
"Invalid slot identifier: " + slot);
}
|
public static void | closeConnection(Handle h)Closes the connection.
h.opened = false;
synchronized (sync[h.slot]) {
if (h.cardSessionId != h.getCardSessionId()) {
throw new IOException();
}
h.cad.closeChannel(h.channel);
}
|
public static byte[] | exchangeAPDU(Handle h, byte[] apduData)This method takes in the command APDU in the form of a byte array,
converts it into an Apdu object which facilitates the processing
of APDU data and then calls the exchangeAPDU method in CadClient
to send the APDU to the card. If there are no errors, this method
gets the response APDU data from the apdu object and returns that.
synchronized (sync[h.slot]) {
if (cads[h.slot] == null) {
try {
cads[h.slot] = new Cad(h.slot, h.token);
} catch (IOException e) {
throw e;
}
}
if (h.getCardSessionId() == -1) {
throw new IOException("Card removed");
}
if (h.cardSessionId != h.getCardSessionId()) {
throw new InterruptedIOException();
}
if (!h.opened) {
throw new InterruptedIOException("Connection closed");
}
try {
byte[] response = h.cad.exchangeApdu(h, apduData);
if (!h.opened) {
throw new InterruptedIOException("Connection closed");
}
return response;
} catch (InterruptedIOException ie) {
throw ie;
} catch (IOException e) {
freeResources(h.slot);
throw e;
}
}
|
private static void | freeResources(int slotNumber)Frees up connection resources if connection was closed because
of an error.
if (cads[slotNumber] != null) {
cads[slotNumber].freeSystemResources();
}
cads[slotNumber] = null;
|
public static int | getSlotCount()Returns the number of slots.
try {
init();
}
catch (IOException e) {
return 0;
}
return cads.length;
|
private static synchronized void | init()This method reads the configuration file for number of slots
and their parameters and performs necessary initialization.
if (cads != null) {
return;
}
try {
SlotFactory.init();
}
catch (CardDeviceException e) {
throw new IOException("Config error: " + e.getMessage());
}
int slots = SlotFactory.getCardSlotCount();
sync = new Object[slots];
for (int i = 0; i < slots; i++) {
sync[i] = new Object();
}
cads = new Cad[slots];
|
public static void | initACL(int slot, com.sun.midp.security.SecurityToken securityToken)Initializes ACL for the slot.
try {
init();
synchronized (sync[slot]) {
if (cads[slot] == null) {
cads[slot] = new Cad(slot, securityToken);
}
cads[slot].initACL();
}
} catch (IOException e) {} // ignored
|
public static boolean | isSatSlot(int slot)Checks if this slot is SAT slot.
init();
return SlotFactory.isSatSlot(slot);
|
public static Handle | openACLConnection(byte[] apdu, int slot, com.sun.midp.security.SecurityToken securityToken)Opens a connection to a smart card for reading of ACL.
This method is called from initACL
method, so it does not need synchronized
statement.
Handle h = null;
init();
try {
if (cads[slot] == null) {
cads[slot] = new Cad(slot, securityToken);
}
} catch (IOException e) {
freeResources(slot);
throw new ConnectionNotFoundException("" + e);
}
try {
return new Handle(slot,
cads[slot].selectApplication(true, apdu),
securityToken);
} catch (IOException e) {
if (cads[slot].isAlive()) {
cads[slot].clean();
throw e;
}
// at this point we need to close slot
freeResources(slot);
throw e;
}
|
static Handle | openSATConnection(int slot, com.sun.midp.security.SecurityToken securityToken)This method is called when there is SAT connection creation in
progress. This method checks if the the required CAD objects have
been created or not and creates them. It then checks if the SIM
application has been selected and can be communicated with.
If it is not present, this method throws ConnectionNotFound
exception. If SAT connection is in use this method throws
IOException.
Handle h = null;
init();
/*
* IMPL_NOTE: SATSA spec does not require checking for existence.
* JDTS test does not close old connection and tries open new one.
*/
if (false) {
// Check if old SAT connection still alive
if (satHandle != null &&
satHandle.opened &&
satHandle.cad.getCardSessionId() != -1 &&
satHandle.cardSessionId == satHandle.cad.getCardSessionId()) {
throw new IOException("SAT already open");
}
}
synchronized (sync[slot]) {
try {
if (cads[slot] == null) {
cads[slot] = new Cad(slot, securityToken);
}
} catch (IOException e) {
freeResources(slot);
throw new ConnectionNotFoundException("" + e);
}
String satAPDU = Configuration.getProperty(SAT_APDU_PROP);
if (satAPDU != null) {
byte[] apdu = new byte[24];
boolean ok;
try {
int len = parseDottedBytes(satAPDU, apdu, 0);
ok = len >= 10 && len <= 22; // 5 bytes hdr + AID + Le
int Lc = (apdu[4] & 0xFF);
if (ok && (len < Lc + 5 ||
len > Lc + 5 + 1 ||
apdu[0] != (byte)0x00 ||
apdu[1] != (byte)0xA4 ||
apdu[2] != (byte)0x04)) {
ok = false;
}
if (ok && len == Lc + 5) {
apdu[len] = 0x7F;
}
} catch (NullPointerException npe) {
ok = false;
} catch (IndexOutOfBoundsException iobe) {
ok = false;
} catch (IllegalArgumentException iae) {
ok = false;
}
if (ok) {
try {
h = new Handle(slot,
cads[slot].selectApplication(true, apdu),
securityToken);
} catch (IOException e) {
if (cads[slot].isAlive()) {
cads[slot].clean();
throw e;
}
// at this point we need to close socket
freeResources(slot);
throw e;
}
}
}
if (h == null) {
if (!cads[slot].isAlive()) {
throw new ConnectionNotFoundException("SIM not found");
}
h = new Handle(slot, 0, securityToken);
}
satHandle = h; // Save handle created for SAT connection
return h;
}
|
public static int | parseDottedBytes(java.lang.String src, byte[] dest, int offset)Parses string that contains hexadecimal byte values separated by
dots. May throw runtime exceptions.
int i = 0;
int len = 0;
int j;
while (i != src.length() + 1) {
if ((j = src.indexOf('.", i)) == -1) {
j = src.length();
}
int l = Integer.parseInt(src.substring(i, j), 16);
if (l != (l & 0xff)) {
throw new IllegalArgumentException();
}
dest[offset + len++] = (byte) l;
i = j + 1;
}
return len;
|
public static Handle | selectApplication(byte[] selectAPDU, int slot, com.sun.midp.security.SecurityToken securityToken)This method is called when there is a connection creation is in
progress
and specifically card application selection is required. This method
checks if the the required CAD objects have been created or not and
creates them. It then calls the selectApplication method on the CAD to
select the application. If the card application selection is successful
this method gets the channel information from the CAD which it returns
to the APDUConnection object.
init();
synchronized (sync[slot]) {
try {
if (cads[slot] == null) {
cads[slot] = new Cad(slot, securityToken);
}
} catch (IOException e) {
freeResources(slot);
throw new ConnectionNotFoundException("" + e);
}
try {
return new Handle(slot,
cads[slot].selectApplication(false, selectAPDU),
securityToken);
} catch (IOException e) {
if (cads[slot].isAlive()) {
cads[slot].clean();
throw e;
}
// at this point we need to close slot
freeResources(slot);
throw e;
}
}
|