Java tutorial
/* * IsmbSnepConnectionTarget * * Copyright (C) 2013 Antonio Lotito <lotito@ismb.it> * * This file is part of ISMB-SNEP-JAVA LIBRARY. * * ISMB-SNEP-JAVA LIBRARY is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version. * * ISMB-SNEP-JAVA LIBRARY 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with ISMB-SNEP-JAVA-LIBRARY. If not, see http://www.gnu.org/licenses/. */ package NFC; import java.io.BufferedReader; import java.io.IOException; import java.io.OutputStream; import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; import javax.smartcardio.CardTerminal; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; import org.apache.commons.io.IOUtils; import Arduino.SerialClass; import Utils.Authentication; @SuppressWarnings("restriction") public class IsmbSnepConnectionTarget { //USEFUL APDU COMMANDS private final static byte TG_GET_DATA = (byte) 0x86; //private final static byte TG_GET_DATA = (byte) 0x86; private final static byte TG_INIT_AS_TARGET = (byte) 0x8c; private final static byte TG_SET_DATA = (byte) 0x8e; private CardTerminal terminal; private CardChannel ch; private Card card; // Enable debugMode to print info about the communication private boolean debugMode = false; public static BufferedReader input; public static OutputStream output; //Set debug mode public void setDebugMode() { debugMode = true; } //Unset debug mode public void unsetDebugMode() { debugMode = false; } /** * Initialize SNEP Connection * * @param t * a valid card terminal * * @throws IsmbSnepException * if the terminal is incorrect */ public IsmbSnepConnectionTarget(CardTerminal t) throws IsmbSnepException { if (t == null) { throw new IsmbSnepException("invalid card terminal"); } terminal = t; try { //if (terminal.isCardPresent()) { if (terminal.waitForCardPresent(5000)) { card = terminal.connect("*"); System.out.println("card: " + card); ch = card.getBasicChannel(); System.out.println("Protocol:" + card.getProtocol()); } else { throw new IsmbSnepException("Device not supported, only ACS ACR122 is supported now"); } } catch (CardException e) { throw new IsmbSnepException("problem with connecting to reader"); } } /** * Sends and receives APDUs to and from the controller * * @param instr * Instruction * @param param * Payload to send * * @return The response payload */ private byte[] transceive(byte instr, byte[] payload) throws IsmbSnepException { if (ch == null) { throw new IsmbSnepException("channel not open"); } int payloadLength = (payload != null) ? payload.length : 0; byte[] instruction = { (byte) 0xd4, instr }; //ACR122 header byte[] header = { (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) (instruction.length + payloadLength) }; /* construct the command */ byte[] cmd = Util.appendToByteArray(header, instruction, 0, instruction.length); cmd = Util.appendToByteArray(cmd, payload); if (debugMode) Util.debugAPDUs(cmd, null); try { CommandAPDU c = new CommandAPDU(cmd); ResponseAPDU r = ch.transmit(c); byte[] ra = r.getBytes(); if (debugMode) Util.debugAPDUs(null, ra); /* check whether APDU command was accepted by the Controller */ if (r.getSW1() == 0x63 && r.getSW2() == 0x27) { throw new CardException("wrong checksum from contactless response"); } else if (r.getSW1() == 0x63 && r.getSW2() == 0x7f) { throw new CardException("wrong PN53x command"); } else if (r.getSW1() != 0x90 && r.getSW2() != 0x00) { throw new CardException("unknown error"); } return Util.subByteArray(ra, 2, ra.length - 4); } catch (CardException e) { throw new IsmbSnepException("problem with transmitting data"); } } public void sendingProcedure() { } public void receivingProcedure() throws IOException { System.out.println("Called new Procedure to receive data .. TARGET MODE"); try { //TG_INIT_AS_TARGET byte[] targetPayload = { //(byte) 0x00, //MODE (byte) 0x02, //DEP ONLY //(byte) 0x01, //PASSIVE MODE ONLY (byte) 0x00, (byte) 0x00, (byte) 0x00, //MIFARE PARAMS (byte) 0x00, (byte) 0x00, (byte) 0x40, //MIFARE PARAMS (byte) 0x01, (byte) 0xfe, (byte) 0x0f, (byte) 0xbb, (byte) 0xba, (byte) 0xa6, //FELICA PARAMS (byte) 0xc9, (byte) 0x89, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, //FELICA PARAMS (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, //FELICA PARAMS (byte) 0x01, (byte) 0xfe, (byte) 0x0f, (byte) 0xbb, (byte) 0xba, //NFCID3t (byte) 0xa6, (byte) 0xc9, (byte) 0x89, (byte) 0x00, (byte) 0x00, //NFCID3t (byte) 0x0F, //LEN Gt (byte) 0x46, (byte) 0x66, (byte) 0x6D, //LLCP WORD (byte) 0x01, (byte) 0x01, (byte) 0x10, //VERSION NUMBER (byte) 0x03, (byte) 0x02, (byte) 0x00, (byte) 0x01, //WELL KNOWN SERVICE LIST (byte) 0x04, (byte) 0x01, (byte) 0x96 //LINK TIMEOUT }; transceive(TG_INIT_AS_TARGET, targetPayload); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(200); } catch (InterruptedException e1) { e1.printStackTrace(); } try { //GETDATA transceive(TG_GET_DATA, null); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } //WAIT FOR A Connect request while (true) { try { byte[] targetPayload = { (byte) 0x00, (byte) 0x00, }; transceive(TG_SET_DATA, targetPayload); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } try { //GETDATA byte[] array = transceive(TG_GET_DATA, null); if ((byte) array[1] == (byte) 0x11) { //RECEIVE SOMETHING SIMILAR TO 0x11 0x20 break; } } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } } //SEND CC - CONNECTION COMPLETE try { byte[] targetPayload = { (byte) 0x81, (byte) 0x84 }; transceive(TG_SET_DATA, targetPayload); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } //WAIT FOR A SNEP REQUEST while (true) { try { byte[] targetPayload = { (byte) 0x00, (byte) 0x00, }; transceive(TG_SET_DATA, targetPayload); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } /** * The main part of communication between reader and arduino */ try { //GETDATA byte[] array = transceive(TG_GET_DATA, null); System.out.println("Income data length: " + array.length); if (array.length > 5) { //Initial a serial communication channel and pass this data to Arduino board //String stringFromArray = Util.byteArrayToAsciiString(array); String stringFromArray = IOUtils.toString(array, "UTF-8"); //System.out.println("Something received: \n"+ " Hex:" + Util.bytesToHex(array) + "\n ASCII:" + Util.byteArrayToAsciiString(array)); System.out.println("Something received: \n" + stringFromArray); serialCommWithArduino(stringFromArray); break; } } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } } //SNEP REQUEST RECEIVED try { byte[] targetPayload = { (byte) 0x83, (byte) 0x44, (byte) 0x01 }; //Receive Ready transceive(TG_SET_DATA, targetPayload); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } try { //GETDATA byte[] array = transceive(TG_GET_DATA, null); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } try { byte[] targetPayload = { (byte) 0x83, (byte) 0x04, (byte) 0x01, (byte) 0x10, (byte) 0x81, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 //LENGTH }; transceive(TG_SET_DATA, targetPayload); } catch (IsmbSnepException e) { e.printStackTrace(); } //WAIT FOR RR try { Thread.sleep(600); } catch (InterruptedException e1) { e1.printStackTrace(); } try { //GETDATA byte[] array = transceive(TG_GET_DATA, null); } catch (IsmbSnepException e) { e.printStackTrace(); } try { byte[] targetPayload = { (byte) 0x00, (byte) 0x00, }; transceive(TG_SET_DATA, targetPayload); } catch (IsmbSnepException e) { e.printStackTrace(); } try { //GETDATA byte[] array = transceive(TG_GET_DATA, null); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } try { byte[] targetPayload = { (byte) 0x81, (byte) 0xC4, (byte) 0x00 }; //Disconnected Mode transceive(TG_SET_DATA, targetPayload); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } try { //GETDATA byte[] array = transceive(TG_GET_DATA, null); } catch (IsmbSnepException e) { e.printStackTrace(); } try { Thread.sleep(300); } catch (InterruptedException e1) { e1.printStackTrace(); } } private void serialCommWithArduino(String arg) { // TODO Auto-generated method stub try { SerialClass obj = new SerialClass(); obj.initialize(); //wait for arduino board's initialization, o.w. the board will fail to get input Thread.sleep(2000); int c = 0; String Token = arg.substring(arg.length() - 119); System.out.println("the full token is>> " + Token); c = Authentication.authenticate(Token); input = SerialClass.input; output = SerialClass.output; switch (c) { case 0: SerialClass.writeData("0"); System.out.println("Authentication failed>> " + Token); break; case 1: SerialClass.writeData("1"); System.out.println("the input beam is>> " + Token); break; case 3: System.exit(0); } String inputLine = input.readLine(); System.out.println(inputLine); obj.close(); } catch (Exception e) { } } }