Hey guys i'll like to do the project call "RFID Management System"
I found some samlpe code from some websites and add a few codes into it.
My RFID can read the number from mifare card right now, but I Already face the problem : How to create a loop for my RFID machine in order to read the card again and again without pushing the "RUN" button in Eclipse
import java.util.List;
import javax.smartcardio.*;
import javax.xml.bind.DatatypeConverter;
public class Blog {
public static void main(String[] args) {
try {
// Display the list of terminals
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
// Use the first terminal
CardTerminal terminal = terminals.get(0);
// Connect wit hthe card
Card card = terminal.connect("*");
System.out.println("card: " + card);
CardChannel channel = card.getBasicChannel();
// Send Select Applet command
ResponseAPDU answer = channel.transmit(new CommandAPDU(new byte[] { (byte)0xFF, (byte)0xCA, (byte)0x00, (byte)0x00, (byte)0x00 } ));
// Send test command
answer = channel.transmit(new CommandAPDU(new byte[] { (byte)0xFF, (byte)0xCA, (byte)0x00, (byte)0x00, (byte)0x00 } ));
byte r[] = answer.getData();
String hex = DatatypeConverter.printHexBinary(answer.getBytes());
System.out.println("Response: " + hex);
// Disconnect the card
card.disconnect(false);
} catch(Exception e) {
System.out.println("Ouch: " + e.toString());
}
}
}
U might be aware of arduino programming , right?, there we have a loop function(), so whatever code we write inside it loops for ever. That is the logic for these things (like rfid, finger print scanner, temp sensors, motion detectors etc) . So use the same technology here. Put ur code inside a
while(1){
}
loop.
This will iterate ur code for ever. hence u will get the desired o/p. U can flash ur card as many times as u want.
Make sure that the code for reading and processing the data should only come inside the loop. Otherwise it takes much memory and may crash ur code.
Related
I am trying to read the data from an NFC card I have for a project. It is using Mifare classic 1k and has 16 sectors.
I am able to connect to the card and I'm trying to read the data (I know the data that I want is in the 2nd sector - 2nd Block). I can scan the card fine and it shows me the size of the card so this ensures me that the card is being scanned properly but the data I get when I Log the "data.readBlock(2)" is just the same as the key I use to authenticate it.
What I understand from the code:
Card connects
Auth == true
I can get overall details of the card such as sector count / block count
protected void onNewIntent(Intent intent){
super.onNewIntent(intent);
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareClassic tag = MifareClassic.get(tagFromIntent) ;
try {
//Variables
int sectorCount = tag.getSectorCount();
int tagSize = tag.getSize();
boolean auth;
//Keys
byte[] defaultKeys = new byte[]{};
defaultKeys = MifareClassic.KEY_DEFAULT;
//Connecting to tag
tag.connect();
//auth = true
auth = tag.authenticateSectorWithKeyA(2, defaultKeys);
byte[] data = tag.readBlock(2);
Log.i("OnNewIntent", "Data in sector 2: " + Arrays.toString(data));
} catch (IOException e) {
e.printStackTrace();
}
Expected = "Data in sector 2: The data in sector 2 block 2"
Actual = "Data in sector 2: [B#4df9e32"
The above Actual result changes each time the card is scanned.
What you are getting is the object reference Java uses to keep it in memory. To get a readable version of the data instead use:
Arrays.toString(data);
By the way, you may want to change your code to check if the authentication was successful:
authSuccessful = mfc.authenticateSectorWithKeyA(sector, key);
if(authSuccessful){
// Read the block
creditBlock = mfc.readBlock(block);
String bytesString = Arrays.toString(creditBlock);
Log.i(TAG, bytesString);
} else {
Log.e(TAG, "Auth Failed");
}
Finally, I'm pretty sure what you are trying to do is just the standard Mifare card read so avoid jumping to conclusions. As they say in medicine:
Think horses, not zebras
I have fixed this problem eventually by converting the memory location to a string and then converting that string to a UTF-8 format. Cheers for the help
In my code i have made my JtextArea public and in my code i have called the jtextare and setTextArea however when i press that button because its a thread it doesnt allow me to change the JTextArea whenever my scanner works
public void scan() throws InterruptedException {
try {
//This is the part i called it but doesnt change the jtextfield into getUid
Login login = new Login();
login.jTextField_username.setText(getUid);
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
CardTerminal terminal = terminals.get(0);
System.out.println("Waiting for a card..");
if (terminal == null) {
return;
}
terminal.waitForCardPresent(0);
Card card = terminal.connect("T=1");
System.out.println("Card: " + card);
System.out.println("Protocol: " + card.getProtocol());
CardChannel channel = card.getBasicChannel();
ResponseAPDU response = channel.transmit(new CommandAPDU(new byte[]{(byte) 0xFF, (byte) 0xCA, (byte) 0x00, (byte) 0x00, (byte) 0x00}));
System.out.println("Response: " + response.toString());
if (response.getSW1() == 0x63 && response.getSW2() == 0x00) {
System.out.println("Failed");
}
System.out.println("UID: " + bin2hex(response.getData()));
getUid = bin2hex(response.getData());
} catch (CardException ex) {
Logger.getLogger(CardId.class.getName()).log(Level.SEVERE, null, ex);
}
}
Note that we cannot compile nor run a code snippet, and so any answer given will need to include guesses, but that being said, I think that the problem is that you have a faulty assumption here:
//This is the part i called it but doesnt change the jtextfield into getUid
Login login = new Login(); // **** A ****
login.jTextField_username.setText(getUid); // **** B ****
At line A you create a new Login object, but is this the actual displayed object? I have a feeling that it's not, that you've already created and displayed the Login window, and are now creating a new one, one never displayed, and on line B are changing its state (the text held in one of its text components). If my guess is correct, then the better solution is to change the state of the actual displayed Login object, not a new and distinct one that you're creating in this method. How to do this? Impossible to state give the information that you've given so far.
If you want a more robust answer, then you will want to create and post a valid [Minimal, Complete, and Verifiable example](Minimal, Complete, and Verifiable example) in with your question -- please check out the link as it will explain all.
Other unrelated issues:
Your question mentions JTextArea, but the code suggests that we're dealing with a JTextField -- which is it?
Your question text suggests that you're mixing Scanner/console input with a Swing GUI. If this is so, I strongly urge you to not go this route, to get all input via the GUI. This will save you hours of debugging and frustration.
I am able to read a smart card from PB's Tactivo smart card reader on Android, however am not familiar with the validation process. Here is an example of what I have to read the input:
...
channel = card.getBasicChannel();
// See www.globalplatform.org for more information about this command.
// CLA = 0x80
// INS = 0xCa
// P1 = 0x9F
// P2 = 0x7F
// Le = 0x00
CommandAPDU GET_DATA_CardProductionLifeCycle = new CommandAPDU(0x80, 0xCA, 0x9F, 0x7F, 0x00);
ResponseAPDU cardResponse;
// Send the command to the card
cardResponse = channel.transmit(GET_DATA_CardProductionLifeCycle);
// Check SW1 if we provided wrong Le
if (cardResponse.getSW1() == 0x6C) {
// Modify the command with correct Le reported by the card in SW2.
GET_DATA_CardProductionLifeCycle = new CommandAPDU(0x80, 0xCA, 0x9F, 0x7F, cardResponse.getSW2());
// Re-send the command but now with correct Le
cardResponse = channel.transmit(GET_DATA_CardProductionLifeCycle);
}
// Check if the card has data for us to collect
if (cardResponse.getSW1() == 0x61) {
// Issue a GET RESPONSE command using SW2 as Le
CommandAPDU GET_RESPONSE = new CommandAPDU(0x00, 0xC0, 0x00, 0x00, cardResponse.getSW2());
cardResponse = channel.transmit(GET_RESPONSE);
}
// Check the final result of the GET DATA CPLC command
if (cardResponse.getSW() != 0x9000) {
// The card does not support Global Platform
System.out.println(String.format("8Card responded with SW:%04x", cardResponse.getSW()));// some sort of SW from the card here... Read as "SW: 6a82
System.out.println("9This card does not support the Global Platform " + "GET CPLC command");
return;
}
// we do not validate the data in this example - we assume that it is
// correct...
...
If anyone has experience with smart card/CAC card valitaion/authentication please give me some guidance, example, or something to work off of. Because There is very little documentation of this out there.
UPDATE:
I have an Android App that I want to secure with a smart card. I am able to read any smart card's input using a Precise Biometrics Tactivo Smart Card reader. How can I validate/authenticate this input to allow only certain users to access the App?
The ATR is inappropriate for validation of any kind, since it is typically shared by thousands of cards.
While cards have a unique identifier (manufacturer specific), this can be easily faked after a valid one has been found out.
The typical means of requiring a certain card (as a component of a two-factor authorization, adding something you have to the something yo know e.g. PIN, password) is execution of an external authentication. Since for that you need to store a key of your own on the card, it will not be an option for a card, which you just happen to possess.
I'm working on a simple program to read a continuous stream of data from a plain old serial port. The program is written in Processing. Performing a simple read of data and dumping into to the console works perfectly fine, but whenever I add any other functionality (graphing,db entry) to the program, the port starts to become de-synchronized and all data from the serial port starts to become corrupt.
The incoming data from the serial port is in the following format :
A [TAB] //start flag
Data 1 [TAB]
Data 2 [TAB]
Data 3 [TAB]
Data 4 [TAB]
Data 5 [TAB]
Data 6 [TAB]
Data 7 [TAB]
Data 8 [TAB]
COUNT [TAB] //count of number of messages sent
Z [CR] //end flag followed by carriage return
So as stated, if I run the program below and simply have it output to the console, it runs fine without issue for several hours. If I add the graphing functionality or database connectivity, the serial data starts to come in garbled and serial port handler is never able to decode the message correctly again. I've tried all sorts of workarounds to this issue, thinking it is a timing problem but reducing the speed of the serial port doesn't seem to make a change.
If you see the serial port handler, I provide a large buffer just in case the terminating Z character is chopped off. I check to make sure the A and Z characters are in the correct place and in turn that the created "substring" is the correct length. When the program starts to fail, the substring will continuously fail this check until the program just crashes. Any ideas? I've tried several different ways of reading the serial port and am just beginning to wonder if I am missing something stupid here.
//Serial Port Tester
import processing.serial.*;
import processing.net.*;
import org.gwoptics.graphics.graph2D.Graph2D;
import org.gwoptics.graphics.graph2D.traces.ILine2DEquation;
import org.gwoptics.graphics.graph2D.traces.RollingLine2DTrace;
import de.bezier.data.sql.*;
SQLite db;
RollingLine2DTrace r1,r2,r3,r4;
Graph2D g;
Serial mSerialport; //the serial port
String[] svalues = new String[8]; //string values
int[] values = new int[8]; //int values
int endflag = 90; //Z
byte seperator = 13; //carriage return
class eq1 implements ILine2DEquation {
public double computePoint(double x,int pos) {
//data function for graph/plot
return (values[0] - 32768);
}
}
void connectDB()
{
db = new SQLite( this, "data.sqlite" );
if ( db.connect() )
{
db.query( "SELECT name as \"Name\" FROM SQLITE_MASTER where type=\"table\"" );
while (db.next())
{
println( db.getString("Name") );
}
}
}
void setup () {
size(1200, 1000);
connectDB();
println(Serial.list());
String portName = Serial.list()[3];
mSerialport = new Serial(this, portName, 115200);
mSerialport.clear();
mSerialport.bufferUntil(endflag); //generate serial event when endflag is received
background(0);
smooth();
//graph setup
r1 = new RollingLine2DTrace(new eq1(),250,0.1f);
r1.setTraceColour(255, 0, 0);
g = new Graph2D(this, 1080, 500, false);
g.setYAxisMax(10000);
g.addTrace(r1);
g.position.y = 50;
g.position.x = 100;
g.setYAxisTickSpacing(500);
g.setXAxisMax(10f);
}
void draw () {
background(200);
//g.draw(); enable this and program crashes quickly
}
void serialEvent (Serial mSerialport)
{
byte[] inBuffer = new byte[200];
mSerialport.readBytesUntil(seperator, inBuffer);
String inString = new String(inBuffer);
String subString = "";
int startFlag = inString.indexOf("A");
int endFlag = inString.indexOf("Z");
if (startFlag == 0 && endFlag == 48)
{
subString = inString.substring(startFlag+1,endFlag);
}
else
{
println("ERROR: BAD MESSAGE DISCARDED!");
subString = "";
}
if ( subString.length() == 47)
{
svalues = (splitTokens(subString));
values = int(splitTokens(subString));
println(svalues);
// if (db.connect()) //enable this and program crashes quickly
// {
// if ( svalues[0] != null && svalues[7] != null)
// {
// statement = svalues[7] + ", " + svalues[0] + ", " + svalues[1] + ", " + svalues[2] + ", " + svalues[3] + ", " + svalues[4] + ", " + svalues[5] + ", " + svalues[6];
// db.execute( "INSERT INTO rawdata (messageid,press1,press2,press3,press4,light1,light2,io1) VALUES (" + statement + ");" );
// }
// }
}
}
While I'm not familiar with your specific platform, my first thought from reading your problem description is that you still have a timing problem. At 115,200bps, data is coming in rather quickly-- more than 10 characters every millisecond. As such, if you spend precious time opening a database (slow file IO) or drawing graphics (also potentially slow), you might well not be able to keep up with the data.
As such, it might be a good idea to put the serial port processing on its own thread, interrupt, etc. That might make the multitasking much easier. Again, this is just an educated guess.
Also, you say that your program "crashes" when you enable the other operations. Do you mean that the entire process actually crashes, or that you get corrupted data, or both? Is it possible that you are overrunning your 200 byte inBuffer[]? At 115kbps, it wouldn't take but 20ms to do so.
I'm trying to communicate between my PC (Windows 7 using Netbeans and RXTX) with an Arduino Pro, using the serial port. The Arduino is actually connected to the PC using an FTDI cable.
The code is based on the Java SimpleRead.Java found here.
Currently the Arduino simply prints out a string when it starts up. My Java program should print the number of bytes that have been read and then print out the contents. The Java program works, sort of...
If the string is long (>10 bytes or so) the output will get broken up.
So if on the Arduino I print
Serial.println("123456789123456789"); //20 bytes including '\r' and '\n'
The output of my Java program may look something like:
Number of Bytes: 15
1234567891234
Number of Bytes: 5
56789
or
Number of Bytes: 12
1234567891
Number of Bytes: 8
23456789
I'm thinking it's a timing problem, because when I manually go through the code using the debugger, the result string is always what it should be: one 20 byte string.
I've been messing with various things but I haven't been able to fix the problem.
Here is the part of the code that is giving me problems:
static int baudrate = 9600,
dataBits = SerialPort.DATABITS_8,
stopBits = SerialPort.STOPBITS_1,
parity = SerialPort.PARITY_NONE;
byte[] readBuffer = new byte[128];
...
...
public void serialEvent(SerialPortEvent event)
{
if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
if (input.available() > 0) {
//Read the InputStream and return the number of bytes read
numBytes = input.read(readBuffer);
String result = new String(readBuffer,0,numBytes);
System.out.println("Number of Bytes: " + numBytes);
System.out.println(result);
}
} catch (IOException e) {
System.out.println("Data Available Exception");
}
}
Serial data is just a stream of data. Depending on when you read it and the buffering that is happening, only part of the data may be available when you read it.
Since you are using line oriented data, what you will want to do is buffer the data until you see the line terminator and only then process the data.
I haven't used Java RXTX, but I've played with Arduino and Processing and it's pretty easy to read/write values from Arduino.
Here is a read sample that comes with Processing(File > Examples > Libraries > Serial > SimpleRead)
/**
* Simple Read
*
* Read data from the serial port and change the color of a rectangle
* when a switch connected to a Wiring or Arduino board is pressed and released.
* This example works with the Wiring / Arduino program that follows below.
*/
import processing.serial.*;
Serial myPort; // Create object from Serial class
int val; // Data received from the serial port
void setup()
{
size(200, 200);
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
// On Windows machines, this generally opens COM1.
// Open whatever port is the one you're using.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw()
{
if ( myPort.available() > 0) { // If data is available,
val = myPort.read(); // read it and store it in val
}
background(255); // Set background to white
if (val == 0) { // If the serial value is 0,
fill(0); // set fill to black
}
else { // If the serial value is not 0,
fill(204); // set fill to light gray
}
rect(50, 50, 100, 100);
}
/*
// Wiring / Arduino Code
// Code for sensing a switch status and writing the value to the serial port.
int switchPin = 4; // Switch connected to pin 4
void setup() {
pinMode(switchPin, INPUT); // Set pin 0 as an input
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop() {
if (digitalRead(switchPin) == HIGH) { // If switch is ON,
Serial.print(1, BYTE); // send 1 to Processing
} else { // If the switch is not ON,
Serial.print(0, BYTE); // send 0 to Processing
}
delay(100); // Wait 100 milliseconds
}
*/
As far as I remember, the baud thingy you setup in Arduino when you instantiate Serial is pretty important. If you use 9600 to send for example, you should use the same number to listen.
Also it's pretty important to send your information as BYTE, otherwise you'll have stuff like \r or \n in the way.
Shorter version, try:
Serial.println(123456789123456789,BYTE);
The simpler the better.
I think you need to use event driven design patterns to solve this problem. I highly recommend you to visit: http://www.whatisarduino.org/bin/Tutorials/Java+Serial+API+and+Arduino