From f387b004982e866a6efe5e09e55bad688082aee1 Mon Sep 17 00:00:00 2001 From: jdkbx Date: Fri, 13 Mar 2009 01:39:47 +0100 Subject: [PATCH] import of midlet code --- .project | 35 ++ Application Descriptor | 7 + src/nfc/BluetoothNFCReader.java | 918 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 960 insertions(+) create mode 100644 .project create mode 100644 Application Descriptor create mode 100644 src/nfc/BluetoothNFCReader.java diff --git a/.project b/.project new file mode 100644 index 0000000..a19e981 --- /dev/null +++ b/.project @@ -0,0 +1,35 @@ + + + BluetoothNFCReader + + + + + + eclipseme.core.preprocessor + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.mtj.core.preverifier + + + + + eclipseme.core.preverifier + + + + + + org.eclipse.jdt.core.javanature + eclipseme.core.nature + eclipseme.core.preprocessingNature + org.eclipse.mtj.core.nature + + diff --git a/Application Descriptor b/Application Descriptor new file mode 100644 index 0000000..36d42ca --- /dev/null +++ b/Application Descriptor @@ -0,0 +1,7 @@ +MIDlet-Version: 1.0.0 +MIDlet-Vendor: Kristian +MIDlet-Jar-URL: Bluetooth.jar +MicroEdition-Configuration: CLDC-1.1 +MicroEdition-Profile: MIDP-2.0 +MIDlet-1: Bluetooth,,de.bdr.stop.Bluetooth +MIDlet-Name: BT-PCSC-Reader diff --git a/src/nfc/BluetoothNFCReader.java b/src/nfc/BluetoothNFCReader.java new file mode 100644 index 0000000..002202b --- /dev/null +++ b/src/nfc/BluetoothNFCReader.java @@ -0,0 +1,918 @@ +/** + * + */ +package nfc; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Vector; + +import javax.bluetooth.BluetoothStateException; +import javax.bluetooth.DataElement; +import javax.bluetooth.DeviceClass; +import javax.bluetooth.DiscoveryAgent; +import javax.bluetooth.DiscoveryListener; +import javax.bluetooth.LocalDevice; +import javax.bluetooth.RemoteDevice; +import javax.bluetooth.ServiceRecord; +import javax.bluetooth.UUID; +import javax.microedition.contactless.ContactlessException; +import javax.microedition.contactless.DiscoveryManager; +import javax.microedition.contactless.TargetListener; +import javax.microedition.contactless.TargetProperties; +import javax.microedition.contactless.TargetType; +import javax.microedition.contactless.sc.ISO14443Connection; +import javax.microedition.io.Connector; +import javax.microedition.io.StreamConnection; +import javax.microedition.io.StreamConnectionNotifier; +import javax.microedition.lcdui.Command; +import javax.microedition.lcdui.CommandListener; +import javax.microedition.lcdui.Display; +import javax.microedition.lcdui.Displayable; +import javax.microedition.lcdui.Form; +import javax.microedition.lcdui.List; +import javax.microedition.lcdui.TextBox; +import javax.microedition.lcdui.TextField; +import javax.microedition.midlet.MIDlet; +import javax.microedition.midlet.MIDletStateChangeException; + + +/** + * @author x_beilkk + * + */ +public class BluetoothNFCReader extends MIDlet implements TargetListener, + CommandListener, DiscoveryListener { + + private Display display; + private Form formStart; + private Form formServerStart; + private Form formConnect; + private Form formDiscover; + private Form formReader; + private Form formLog; + private Form formError; + private TextField tfIn; + private TextField tfOut; + private TextField tfReadIn; + private TextField tfWriteOut; + //private TextField msgTf; + private Command cmdCancel; + private Command cmdDiscover; + private Command cmdSelect; + private Command cmdExit; + private Command cmdServer; + private Command cmdLog; + private Command cmdBack; + private Command cmdRemove; + private String uid; + + /** currently selected target type. cards or tags.*/ + private TargetType currTargetType = null; + + /** connection to use for card communication.*/ + private ISO14443Connection isoConn = null; + + private DiscoveryAgent discoveryAgent; + private Vector devices; + + private List deviceList; + + private StreamConnection connection; + + private String serviceURL; + private byte[] buffer; + //UUID SPP_UUID = new UUID("1101", true); + long SPP_UUID = 0x1101; + static int SERVICE_NAME_ATTRID = 0x0100; + + private boolean isCardPresent = false; + + Reader r = new Reader(); + + /* (non-Javadoc) + * @see javax.microedition.midlet.MIDlet#destroyApp(boolean) + */ + protected void destroyApp(boolean arg0) throws MIDletStateChangeException { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see javax.microedition.midlet.MIDlet#pauseApp() + */ + protected void pauseApp() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see javax.microedition.midlet.MIDlet#startApp() + */ + protected void startApp() throws MIDletStateChangeException { + display = Display.getDisplay(this); + + initCommands(); + initForms(); + + display.setCurrent(formStart); + uid = ""; + } + + private void initCommands() { + cmdCancel = new Command("Cancel", Command.CANCEL, 1); + cmdDiscover = new Command("Discover", Command.ITEM, 1); + cmdSelect = new Command("Select", Command.OK, 1); + cmdExit = new Command("Exit", Command.EXIT, 1); + cmdServer = new Command("Server", Command.ITEM, 1); + cmdLog = new Command("Log", Command.ITEM, 1); + cmdBack = new Command("Back", Command.BACK, 1); + cmdRemove = new Command("Remove", Command.ITEM, 1); + } + + private void initForms() { + formStart = new Form("Bluetooth Reader"); + formServerStart = new Form("Server"); + formConnect = new Form("Connect"); + formDiscover = new Form("Discover"); + formReader = new Form("Reader"); + formLog = new Form("Log"); + formError = new Form("Error"); + tfIn = new TextField("Last APDU", "", 520, TextField.UNEDITABLE); + tfOut = new TextField("Last RAPDU", "", 520, TextField.UNEDITABLE); + tfReadIn = new TextField("APDU size", "", 25, TextField.UNEDITABLE); + tfWriteOut = new TextField("RAPDU size and responsecode", "", 12, TextField.UNEDITABLE); + setupForms(); + } + + private void setupForms() { + resetFormStart(); + resetFormServerStart(); + resetFormConnect(); + resetFormDiscover(); + resetFormReader(); + resetFormLog(); + resetFormError(); + } + + private void resetFormError() { + formError.deleteAll(); + formError.setTitle("Error"); + formError.addCommand(cmdCancel); + formError.addCommand(cmdExit); + formError.addCommand(cmdLog); + formError.setCommandListener(this); + } + + private void resetFormServerStart() { + formServerStart.deleteAll(); + formServerStart.setTitle("Server"); +// msgTf = new TextField("msg:", "", 256, TextField.ANY); +// formDisplay.append(msgTf); + formServerStart.addCommand(cmdCancel); + formServerStart.setCommandListener(this); + } + + private void resetFormConnect() { + formConnect.deleteAll(); + formConnect.setTitle("Connect"); + formConnect.append("\n\n connect card!"); + formConnect.addCommand(cmdCancel); + formConnect.setCommandListener(this); + } + + private void resetFormDiscover() { + formDiscover.deleteAll(); + formDiscover.setTitle("Discover"); + formDiscover.addCommand(cmdCancel); + formDiscover.setCommandListener(this); + } + + private void resetFormReader() { + formReader.deleteAll(); + formReader.setTitle("Reader"); + formReader.append(tfReadIn); + formReader.append(tfWriteOut); + formReader.addCommand(cmdCancel); + formReader.addCommand(cmdLog); + formReader.addCommand(cmdRemove); + formReader.setCommandListener(this); + } + + private void resetFormStart() { + formStart.deleteAll(); + formStart.setTitle("Bluetooth Reader"); + formStart.addCommand(cmdServer); + formStart.addCommand(cmdDiscover); + formStart.addCommand(cmdExit); + formStart.setCommandListener(this); + } + + private void resetFormLog() { + formLog.deleteAll(); + formLog.setTitle("Log"); + formLog.append(tfIn); + formLog.append(tfOut); + formLog.addCommand(cmdBack); + formLog.setCommandListener(this); + } + + private static String toHexString(byte[] value, int offset, int len) { + if (value == null) + return "null"; + + if (len < 1 || offset < 0 || offset + 1 > value.length) { + return "null"; + } + + StringBuffer result = new StringBuffer(); + + for (int i = 0; i + offset < value.length && i < len; i++) { + result.append(Integer.toHexString((value[i + offset] >>> 4) & 0x0F).toUpperCase()); + result.append(Integer.toHexString(value[i + offset] & 0xF).toUpperCase()); + } + return result.toString(); + } + + private static byte[] toByteArray(String string) { + if (string.length() % 2 != 1) { + byte[] result = new byte[string.length() / 2]; + for (int i = 0; i < result.length; i++) { + result[i] = (byte) Integer.parseInt(string.substring(2 * i, + 2 * i + 2), 16); + } + return result; + } else { + return null; + } + } + + // Starts the search for the Bluetooth devices + private void btSearch() { + + // Set the right UI + deviceList = new List("Searcing devices", List.IMPLICIT); + deviceList.setSelectCommand(cmdSelect); + deviceList.addCommand(cmdCancel); + deviceList.setCommandListener(this); + display.setCurrent(deviceList); + + devices = new Vector(); + // Start an inquiry to find Bluetooth devices + try { + LocalDevice local = LocalDevice.getLocalDevice(); + discoveryAgent = local.getDiscoveryAgent(); + discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this); + + } catch (BluetoothStateException e) { + formLog.append(e.getMessage()); + } + } + + /* (non-Javadoc) + * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable) + */ + public void commandAction(Command cmd, Displayable displayForm) { + + if (displayForm == formStart) { + if (cmd == cmdDiscover) { + formStart.append("starting client\n"); + btSearch(); + } else if (cmd == cmdServer) { + formStart.append("starting server\n"); + startServer(); + } + } else if (displayForm == deviceList) { + if (cmd == cmdCancel) { + discoveryAgent.cancelInquiry(this); + resetFormStart(); + display.setCurrent(formStart); + } else if (cmd == cmdExit) { + notifyDestroyed(); + } else if (cmd == cmdSelect) { + if (deviceList.getSelectedIndex() != deviceList.size() - 1) { + RemoteDevice btDevice = (RemoteDevice) devices + .elementAt(deviceList.getSelectedIndex()); + startClient(btDevice); + } + } + } else if (displayForm == formError) { + if (cmd == cmdCancel) { + resetFormStart(); + disconnectCard(formError, true); + r.kill(); + display.setCurrent(formStart); + } else if (cmd == cmdLog) { + display.setCurrent(formLog); + } + } else if (displayForm == formReader) { + if (cmd == cmdCancel) { + resetFormStart(); + disconnectCard(formError, true); + r.kill(); + if (connection != null) { + try { + connection.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + connection = null; + } + display.setCurrent(formStart); + } else if (cmd == cmdLog) { + display.setCurrent(formLog); + } else if (cmd == cmdRemove) { + disconnectCard(formError, true); + startSmartCardDiscovery(); + resetFormConnect(); + display.setCurrent(formConnect); + } + } else if (displayForm == formLog) { + if (cmd == cmdBack) { + display.setCurrent(formReader); + } else if (cmd == cmdCancel) { + resetFormStart(); + disconnectCard(formError, true); + r.kill(); + if (connection != null) { + try { + connection.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + connection = null; + } + display.setCurrent(formStart); + } + } else if (displayForm == formServerStart) { + if (cmd == cmdCancel) { + resetFormStart(); + r.kill(); + display.setCurrent(formStart); + } + } else if (displayForm == formConnect) { + if (cmd == cmdCancel) { + resetFormStart(); + r.kill(); + if (connection != null) { + try { + connection.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + connection = null; + } + display.setCurrent(formStart); + } + } + //else if (displayForm == formDisplay) { +// if (cmd == cancelCmd) { +// display.setCurrent(form); +// form.addCommand(discoverCmd); +// } +// } else + if (cmd == cmdExit) { + try { + destroyApp(true); + } catch (MIDletStateChangeException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + notifyDestroyed(); + return; + } + } + + private void startClient(RemoteDevice btDevice) { + resetFormServerStart(); + display.setCurrent(formServerStart); + formServerStart.append(">>trying to discover remote services\n"); + try { + LocalDevice localDevice = LocalDevice.getLocalDevice(); + DiscoveryAgent agent = localDevice.getDiscoveryAgent(); + UUID[] uuids = new UUID[] {new UUID(SPP_UUID)}; + int[] attrSet = {SERVICE_NAME_ATTRID}; + int id = agent.searchServices(attrSet, uuids, btDevice, this); + formServerStart.append(">>got service: " + id + "\n"); + } catch (BluetoothStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private void startServer() { + resetFormServerStart(); + formServerStart.append(">>starting service\n"); + display.setCurrent(formServerStart); + try { + LocalDevice btDevice = LocalDevice.getLocalDevice(); + btDevice.setDiscoverable(DiscoveryAgent.GIAC); + + serviceURL = "btspp://localhost:" + new UUID(SPP_UUID).toString() + + ";name=SPPServer1"; + StreamConnectionNotifier notifier = + (StreamConnectionNotifier) Connector.open(serviceURL); + formServerStart.append(">>waiting for connection on\n" + + serviceURL + "\n"); + connection = notifier.acceptAndOpen(); +// RemoteDevice rDev = RemoteDevice.getRemoteDevice(connection); +// formServerStart.append(">>remote address: " + rDev.getBluetoothAddress() + "\n"); +// formServerStart.append(">>remote name: " + rDev.getFriendlyName(true) + "\n"); + + startSmartCardDiscovery(); + + // start thread and detach handler + Thread reader = new Thread(r); + reader.start(); + formServerStart.append("started reader\n"); + } catch (BluetoothStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + formServerStart.append(">>done\n"); + } + + private void startSmartCardDiscovery() { + resetFormConnect(); + display.setCurrent(formConnect); + initializeCardDiscManager(); + } + + /* (non-Javadoc) + * @see javax.bluetooth.DiscoveryListener#deviceDiscovered(javax.bluetooth.RemoteDevice, javax.bluetooth.DeviceClass) + */ + public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) { + // When device has been found add it to devices Vector.. + devices.addElement(btDevice); + + // .. and to the deviceList List + String devName; + try { + devName = btDevice.getFriendlyName(false); + + if (devName == null || devName.compareTo("") == 0) { + devName = btDevice.getBluetoothAddress(); + } + deviceList.append(devName, null); + } catch (IOException e) { + } + } + + /* (non-Javadoc) + * @see javax.bluetooth.DiscoveryListener#inquiryCompleted(int) + */ + public void inquiryCompleted(int status) { + // When searching of the devices has completed set title to indicate + // that + if (status == INQUIRY_COMPLETED) { + deviceList.setTitle("Inquiry completed"); + } else if (status == INQUIRY_TERMINATED) { + deviceList.setTitle("Inquiry terminated"); + } else if (status == INQUIRY_ERROR) { + deviceList.setTitle("Inquiry error"); + } + + try { + LocalDevice local = LocalDevice.getLocalDevice(); + String name = local.getFriendlyName(); + if (name == null || name.compareTo("") == 0) { + name = local.getBluetoothAddress(); + } + devices.addElement(local); + deviceList.append(name, null); + } catch (BluetoothStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + synchronized(this) { + try { this.notifyAll(); } catch (Exception e) {} + } + } + + /* (non-Javadoc) + * @see javax.bluetooth.DiscoveryListener#serviceSearchCompleted(int, int) + */ + public void serviceSearchCompleted(int transID, int respCode) { + if (respCode != SERVICE_SEARCH_COMPLETED) { + formServerStart.append(">>service discovery failed " + respCode + "\n"); + return; + } + formServerStart.append(">>service discovery done " + transID + " " + respCode + "\n"); + if (serviceURL == null) { + formServerStart.append("!!url empty, abort\n"); + return; + } + synchronized (this) { + try { this.notifyAll(); } catch (Exception e) {} + } + formServerStart.append(">>connecting to service: " + serviceURL); + try { + connection = (StreamConnection) Connector.open(serviceURL); + startSmartCardDiscovery(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Removes targetListener for ISO cards. + */ + private void removeCardDiscManager() { + currTargetType = TargetType.ISO14443_CARD; + DiscoveryManager dm = DiscoveryManager.getInstance(); + try { + dm.removeTargetListener(this, TargetType.ISO14443_CARD); + } catch (IllegalStateException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + + /** + * Adds Callback for ISO cards. + */ + private void initializeCardDiscManager() { + currTargetType = TargetType.ISO14443_CARD; + DiscoveryManager dm = DiscoveryManager.getInstance(); + try { + dm.removeTargetListener(this, TargetType.ISO14443_CARD); + } catch (IllegalStateException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + try { + dm.addTargetListener(this, TargetType.ISO14443_CARD); + return; + + } catch (IllegalStateException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (ContactlessException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + + /** + * Interface callback, when ICC is detected by reader. + * @param target Properties of the detected ICC + */ + public final void targetDetected(TargetProperties[] target) { + if (currTargetType.equals(TargetType.ISO14443_CARD)) { + cardDetected(target); + } + } + + /** + * Handle a detected smartcard. + * @param target connection + */ + private void cardDetected(final TargetProperties[] target) { + if (!connectExternalCard(target, formConnect)) { + display.setCurrent(formError); + return; + } +// // TODO start thread and detach handler +// startReader(); + isCardPresent = true; + display.setCurrent(formReader); + } + + /** + * Establishes connection to external card. + * @param target to make connection + * @param currentForm where to display messages + * @return success status + */ + private boolean connectExternalCard(final TargetProperties[] target, + Form currentForm) { + Class[] classes = target[0].getConnectionNames(); + + for (int j = 0; j < classes.length; ++j) { + try { + if (isoConn != null) { + disconnectCard(currentForm, false); + } + if (classes[j].equals(Class.forName( + "javax.microedition.contactless.sc.ISO14443Connection"))) { + + String url = target[0].getUrl(classes[j]); + + try { + isoConn = (ISO14443Connection) Connector.open(url); + } catch (IOException e) { + currentForm.append("IOException\n"); + return false; + } + + uid = target[0].getUid(); + currentForm.append("connected\n"); + return true; + } + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + return false; + } + + /** + * Closes connection. + * @param currentForm where to display messages. + * @return true if successful + */ + private boolean disconnectCard(final Form currentForm, boolean removeTargetListener) { + isCardPresent = false; + try { + if (isoConn != null) { + isoConn.close(); + } +// currentForm.append(disconnectStr); + } catch (IOException e) { + currentForm.append("IOException\n"); + return false; + } + if (removeTargetListener) { + removeCardDiscManager(); + } + return true; + } + + + + /* (non-Javadoc) + * @see javax.bluetooth.DiscoveryListener#servicesDiscovered(int, javax.bluetooth.ServiceRecord[]) + */ + public void servicesDiscovered(int transID, ServiceRecord[] records) { + formServerStart.append(">>services discovered #: " + records.length + "\n"); + for (int i = 0; i < records.length; ++i) { + serviceURL = records[i].getConnectionURL( + ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); + DataElement serviceNameElement = records[i].getAttributeValue(SERVICE_NAME_ATTRID); + if (serviceNameElement != null) { + String name = (String) serviceNameElement.getValue(); + formServerStart.append(">>" + name + "\n"); + if (serviceURL.startsWith("btspp") + && name.indexOf("SPPServer1") > -1) { + formServerStart.append(">>got btspp service " + i + "\n"); + break; + } + } + } + } + +public class Reader extends Thread { + + private static final int READER_CMD_LENGTH = 2; + private final byte[] GET_ATTR_CMD = new byte[] {0x20, 0x21}; + private final byte[] GET_PRESENCE_CMD = new byte[] {0x20, 0x22}; + private final byte[] END_BYTES = new byte[] {0x20, 0x23}; + private boolean end = false; + + private final byte[] NULL_BYTES = new byte[] {0x00}; + private final byte[] ONE_BYTES = new byte[] {(byte) 1}; + + public void kill() { + end = true; + } + + public void run() { + formLog.append("started\n"); + end = false; + startReader(); + } + + private void startReader() { + resetFormReader(); + formReader.append(" -- communicating -- \n"); + //display.setCurrent(formReader); + + buffer = new byte[258]; + byte[] response; + byte[] responseLength = new byte[1]; + + try { + OutputStream os = connection.openOutputStream(); + InputStream is = connection.openInputStream(); + + int realLen, readLen, offset, len = 0; + + // reader loop + while(!end) { + realLen = -1; + readLen = 0; + len = 0; + + // get input + while (readLen != realLen) { + len = is.read(buffer, realLen + 1, 255 - readLen); + + if (len < 1) { + try { + sleep(10); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + formReader.append("ending\n"); + return; + } + continue; + } else { + if (realLen < 1) { + realLen = (int) (buffer[0] & 0xFF); + readLen += len -1; + } else { + readLen += len; + } + } + } + + len = readLen; + offset = 1; +// byte[] cmd = new byte[len]; +// for (int i = 0 ; i < readLen; ++i) { +// cmd[i] = buffer[i + 1]; +// } + + // write messages to screen + if (len > 1 && len != READER_CMD_LENGTH) { + tfReadIn.setString(">> " + len + "\n" + + toHexString(buffer, 1, 8)); + tfWriteOut.setString(" \n "); + //tfIn.setString(">>got " + len + " " + toHexString(buffer, 1, 8)); + } + + + + // handle cmds + if (len == READER_CMD_LENGTH) { + //formLog.append("might have gotten cmd\n"); + + if (isEnd(buffer, offset, len)) { + end = true; + formReader.append(">>end command\n"); + formLog.append(">>end command\n"); + break; + } + + if (equal(GET_ATTR_CMD, buffer, len)) { + formLog.append(">>atr\n"); + responseLength[0] = (byte) (0xFF & uid.length()); + os.write(responseLength); + os.write(uid.getBytes()); + os.flush(); + continue; + } + + if (equal(GET_PRESENCE_CMD, buffer, len)) { + //formLog.append(">>presence\n"); + responseLength[0] = 1; + os.write(responseLength); + if (isCardPresent) { + os.write(ONE_BYTES); + } else { + os.write(NULL_BYTES); + } + os.flush(); + + continue; + } + + formLog.append("matched no cmd\n"); + } else { + //formLog.append("doing real shit\n"); + } + tfIn.setString(toHexString(buffer, 1, len)); + if (isCardPresent) { + response = sendAPDU(buffer, offset, len); + + if (response != null && response.length > 0) { + responseLength[0] = (byte) (0xFF & response.length); + os.write(responseLength); + os.write(response); + os.flush(); + tfWriteOut.setString("<< " + response.length + + "\n" + toHexString(response, response.length - 2, 2)); + tfOut.setString(toHexString(response, 0, response.length)); + } else { + os.write(NULL_BYTES); + os.flush(); + } + } else { + //formLog.append("nuthing done\n"); + os.write(NULL_BYTES); + os.flush(); + } + } + try { + is.close(); + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } catch (IOException e) { + e.printStackTrace(); + formError.append(e.getMessage()); + formError.append("!!Bluetooth error\nrestart necessary\n"); + disconnectCard(formError, true); + display.setCurrent(formError); + return; + } + if (connection != null) { + try { + connection.close(); + } catch (IOException e) { + e.printStackTrace(); + } + connection = null; + } + if (display.getCurrent() == formReader) { + resetFormStart(); + display.setCurrent(formLog);//Start); + } + + } + + + + // TODO own exception throwing + private byte[] sendAPDU(byte[] buffer, int offset, int len) { + if (buffer == null || buffer.length == 0 || len > buffer.length) { + return NULL_BYTES; + } + + byte[] cmd = new byte[len]; + for (int i = 0; i < len; ++i) { + cmd[i] = buffer[i + offset]; + } + + try { + return isoConn.exchangeData(cmd); + } catch (IOException e) { + e.printStackTrace(); + formError.append(e.getMessage()); + formError.append("!!NFC IO error\n"); + formLog.append("!!NFC IO error\n"); + + } catch (ContactlessException e) { + e.printStackTrace(); + formError.append(e.getMessage()); + formError.append("!!NFC contactless error\nrestart necessary\n"); + formLog.append("!!NFC contactless error\n"); + disconnectCard(formError, true); + display.setCurrent(formError); + r.kill(); + } + return NULL_BYTES; + } + + private boolean isEnd(byte [] buffer, int offset, int length) { + return equal(END_BYTES, 0, END_BYTES.length, buffer, offset, length); + } + + private boolean equal(byte[] constCmd, byte[] second, int secondLength) { + return equal(constCmd, 0, constCmd.length, second, 1, secondLength); + } + + private boolean equal(byte[] first, int firstOffset, int firstLength, + byte[] second, int secondOffset, int secondLength) { + if (first == null && second == null) { + //formLog.append("both null\n"); + return true; + } + if (first == null || second == null) { + //formLog.append("one null\n"); + return false; + } + if (firstLength < 1 || firstOffset < 0 + || secondLength < 1 || secondOffset < 0) { + return false; + } + if (firstLength + firstOffset > first.length + || secondLength + secondOffset > second.length) { + //formLog.append("wrong length specified\n"); + return false; + } + if (firstLength != secondLength) { + //formLog.append("length wrong " + first.length + " " + second.length + "\n"); + return false; + } + for (int i = 0; i < firstLength; ++i) { + if (first[i + firstOffset] != second[i + secondOffset]) { + //formLog.append("different " + i + " " + first[i] + " != " + second[i] + "\n"); + return false; + } + } + return true; + } + } +} -- 2.11.4.GIT