I'm a beginner with Android developement and I'm trying to configure a "pass-through" mode for NFC. Basically I2C writes something on an NFC TAG, Mobile Phone picks it up, new data is written by I2C and so on. I kind of struggle with the time the tag is written: Meanwhile, the phone gets an "NAK" and throws back an IOException since transceive fails. How can I properly handle it? I tried with "thread.millis" to wait till I2C is done, but this solution looks pretty crappy and only works with my arduino and phone.
while (Schleife < 1000) {
try {
answer = ultralight.transceive(command); //This one throws an IOException if the data is not ready yet
Schleife = Schleife + 1;
} catch (IOException ioe) {
//Log.e("UnsupportedEncoding", ioe.toString());
}
}
I want the program to re execute the process. One thing I tried was to include the catch statement into the while-loop, but it took forever sometimes to rerun the while loop.
I'm thankful for every answer.
Kind regards
My reading of the datasheet for the chip is that you are looping around transceiving the wrong command.
After a READ or FAST_READ command involving the terminator page of the SRAM, bit SRAM_RF_READY and bit RF_LOCKED are automatically reset to 0b allowing the I2C interface to further write data into the SRAM buffer.To signal to the host that further data is ready to be written, the following mechanisms are in place:•The NFC interface polls/reads the bit SRAM_RF_READY from NS_REG (see Table14) to know if new data has been written by the I2C interface in the SRAM
You loop should be read E8h block and checking the to see if the SRAM is ready to be read by the RF connection, then read 64 bytes with fast read when the right bits are set in byte 0
This is how the chip implements a flow control mechanism between the I2C interface and the RF interface to prevent errors.
update
Ok the implementation sheet shows how to do it without flow control.
For the question how to handle a NACK, first you need to check for it
Below is how I check for a NACK
if ((answer != null) && (answer.length == 1) && ((answer[0] & 0x00A) != 0x00A)) {
// Got NACK
Log.e("Nack", Schleife); //added to identify iteration.
}
It would be helpful to also log the iteration number of any IOException
I'm thinking that the NACK and IO exception are on different iterations.
As a proper NACK is not an IO Exception.
Also Android code the anticollision under the hood, so the only thing you can try when receiving the NACK is close and connect again.
or
A low level transeive to "0x95 0x70 (UID bytes)" be correct
(taken from https://android.googlesource.com/kernel/common/+/android-3.18/net/nfc/digital_technology.c#349 )
"0x95 0x70" I think is the correct Anti-collison command for the card type.
Related
I am trying to read a message from RFID reader connected via USB to windows 10pro machine with usb4java library.
I have managed to claim the interface, opened pipe and registered listener for the data, however the listener is never triggered. The reader acts as keyboard and whatever it reads ends up in active application, such as IDE i have open, instead of in listener.
UsbInterface usbInterface = activeInteface(device);
// there is only one endpoint in the list
UsbEndpoint endpoint = (UsbEndpoint)usbInterface.getUsbEndpoints().get(0);
UsbPipe pipe = endpoint.getUsbPipe();
try {
usbInterface.claim();
// true
System.out.println("claimed usb interface: " + usbInterface.isClaimed());
pipe.open();
// true
System.out.println("pipe open: " + pipe.isOpen());
pipe.addUsbPipeListener(new MessageListener());
// true
System.out.println("pipe active: " + pipe.isActive());
// keep main thread alive, async call should be done from another thread i guess
Thread.sleep(15000);
}
catch (Exception any) {System.out.println(any);}
}
And the listener:
private static class MessageListener implements UsbPipeListener {
#Override
public void errorEventOccurred(UsbPipeErrorEvent event) {
System.out.println(event.toString() + " , " +event.getUsbException());
}
#Override
public void dataEventOccurred(UsbPipeDataEvent event) {
// this code block never triggers
System.out.println("listener ...);
int actualLength = event.getActualLength();
System.out.println("length: " + actualLength);
byte[] data = event.getData();
System.out.println("data length " + data.length);
}
}
i have also tried synchronous read instead of asynchronous in the block above, like this:
byte[] buffer = new data[8];
// this fails on its own, don't even need to read something with RFID reader
int received = pipe.syncSubmit(buffer);
fails with:
USB error1: Transfer error on interrupt endpoint: Input/Output error
There is some windows specific property that library supports: org.usb4java.javax.useUSBDK = true
but this fails when i try to set it with an exception.
I have 0 experience with USB devices so not sure how to proceed from here. Is there something wrong with the code, do i need USBDK or device does not support libUSB driver ? Sadly this is not my device and i don't have access to documentation of the device so cannot be sure if it is device driver issue.
I know that this is 2 years old, but i've had similar issue and this was one of the first questions that i ran into looking for solution, which took me hours.
So, basically, windows doesn't let to read/write keyboard devices directly, to do so, you have to override it's driver (That's why you're getting Input/Output error, and it's written in the hid4java's FAQ).
First way to override device driver is described in libusb wiki.
As far as i know you would have to install a new driver every time you connect the device to a new USB port, which is why i recommend you to read further.
Second way is what you've already mentioned, which is using UsbDk (Usb Drivers Development Kit for Windows). It makes the device accessible for you by detaching the kernel driver and reattaching it back after you're done playing with it.
In order to use it, you need to do two things:
Set the org.usb4java.javax.useUSBDK = true in you javax.usb.properties file as stated in the manual (this can also be done manually in low-level usb4java, see OPTION_USE_USBDK and setOption(Context, int)).
Download and install UsbDk on your system (simplest way is to download x64 or x86 version msi installer which has GUI and is fully automated), which is sadly not in the manual (maybe it's obvious for some people, but took me amount of time that i am not proud of to realize).
Im guessing that the lack of second step is why OP has been getting an exception.
Hope that this will help someone, knowing all this two days ago would save me a lot of headache.
RFID readers operate in keyboard emulation mode by default.
You can normally get a tool from the manufacturer's website to configure the RFID reader.
This will allow you to change the reader to HID mode.
This should resolve your issues.
Sorry for the late response but I hope it helps others.
I would like to ask you a specific question: I'm trying to develop a software switch with the jNetPcap 1.4 library on Java 1.7, the goal is to have a program, that can forward packets received on port no. 1 to port no. 2 and vice versa (just on these two NIC-s).
I can see all the incoming packets on both of the interfaces, but when it comes to forwarding, I have a problem: if I send a packet on interface X with pcap.sendPacket(PcapPacket) the nextPacket() function inside the PcapPacketHandler() class will see it also, and will treat is a "new" packet, insted of just ignoring it, because it was sent by the same Pcap instance.
Is there any way to ignore the packets, that were sent by the pcap.sendPacket(PcapPacket) function (so they do not appear again in the nextPacket() function)?
I don't know much about the underlying winpcap library, but I'm sure SharpPcap in C# has this type of functionality. Doesn't jNetPcap have it also, or am I missing something?
Things I've tried:
Using pcap.inject() instead of pcap.sendPacket(), but my NIC doesn't
seem to support this function
Setting the capture direction to inbound only with
pcap.setDirection(Direction.IN) - this seems to have absolutely no
effect, the packets are captured just as before setting it.
Ps. unfortunately I have to write it in Java, if the jNetPcap library does not have this functionality, please, could you advise how to solve the problem? I'm thinking of buffering the sent packets to an array of some type and checking every newly detected packet to be the same as one packet in the array - but this seems to be a computationally complex solution.
Here's my sample code (not the whole, just the relevant pieces):
// Init
Pcap pcap = Pcap.openLive(devices.get(0).getName(), 64*1024, Pcap.MODE_PROMISCUOUS, 1000, errbuf);
...
PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {
public void nextPacket(PcapPacket packet, String user) {
// The duplicate packet that is sent in the sendAll() function also appears here
// Process the packet and add it to the forwarding buffer if needed
buffer.addPacket(packet);
}
}
// This is called in a separate thread, if some packets were added to the buffer
public void sendAll(){
while(buffer.hasNext() != 0){
pcap.sendPacket(buffer.getNextPacket());
}
}
Same goes for the second interface.
Thank you for your help in advance.
I realize this is an old and maybe not so popular topic, but I finally solved this by adding a buffer and constantly checking for duplicates. Since the code is complex, I decided to post the key functionality and how do I ignore the frame based on jnetpcap.com recommendation.
The code:
// we're inside the nextPacket(PcapPacket currentPacket, String user) method
buffer.lock();
for(int j = 0; j<buffer.size(); j++){
if(currentPacket.getCaptureHeader().caplen() == buffer.get(j).getCaptureHeader().caplen()
&& packet.size() == buffer.get(j).size()){
buffer.erasePacket(j);
return;
}
}
buffer.unlock();
// continue packet processing
Feel free to use it in your project.
I'm trying to read data from the custom made USB device (working as slave) in Android. I was able to write the data to the device with this code:
UsbRequest request = new UsbRequest();
request.initialize(_outConnection, _outEndpoint);
int bufferDataLength = _outEndpoint.getMaxPacketSize();
ByteBuffer buffer = ByteBuffer.allocate(bufferDataLength + 1);
buffer.put(bytes);
if (request.queue(buffer, bufferDataLength)) {
UsbRequest req = _outConnection.requestWait(); }
I see the result on the debug board that my device is connected to.
I'm trying the same approach for reading data, but apparently that doesn't work:
int siz = 1;
ByteBuffer res = ByteBuffer.allocate(siz + 1);
UsbRequest request = new UsbRequest();
request.initialize(_inConnection, _inEndpoint);
request.queue(res, siz); // This return false always
What am I doing wrong? I have no idea of the size of the packet sent back - but I assume that 1 byte I would be always able to read.
My device has HID interface with two interrupt endpoints (IN and OUT)
I have no idea what fixed the problem, but now it works. I have rewritten everything from scratch. I think I didn't use this code (I thought it is for user notification and I don't need that. But appears it is something else) - and that was the main reason why it didn't work:
// Create and intent and request a permission.
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(_context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
_context.registerReceiver(mUsbReceiver, filter);
Several things that I did and which helped me to implement stable connection are:
1) Closing and opening the connection each time I need it. I know this is sounds strange, but this is the only way I could make it stable. If I try to use long-living connection, for some reason it gets corrupted and stops from working after some time.
2) Reading continously in never-ending while loop. I also put some short sleeps in all my threads - that helped to read in more real time manner.
3) Locking the device (synchronized). I do not open both write and read connections simultaneously.
I didn't have much hours assigned for this project, and this project is only a demo - so all of this suited us well. I think if spent a little more time, some of these things could have been rewritten to more nice ones.
I'm connecting from an android device using java to a server running PHP using DefaultHttpClient.
One test I am doing is to check that the java code gracefully handles itself if the server takes to long in sending data back. If it does take to long it disconnects and retries.
Currently I have setup the connection timeout to 3 seconds by:
HttpConnectionParams.setSoTimeout(httpParameters, 3000);
On the server the PHP script is sleeping for 10 seconds:
sleep(10);
The java code works, if the script takes longer than 3 seconds then it throws a java.net.SocketTimeoutException and then retries again after a small amount of time.
The PHP script continues to run which is not what I want. I've tried testing using connection_aborted straight after the sleep function but it does not catch the client disconnect which has already happened.
ignore_user_abort(true);
sleep(10);
print "black hole";
flush();
if(connection_aborted()!=0){
// You would think this works but it does not.
}
Whats the recommended way to handle this?
I actually wrote an article on this very subject not too long ago, I will give a brief answer here, and assume it's ok to also post a related link?
Essentially, PHP will only figure out that a remote client has disconnected when it tries to use the socket that is connected to that remote socket, until you ask it to do anything with that socket it will assume that everything is fine. Here is the code I use to check for remote disconnections:
public function isAlive(){
$res = #socket_recv($this->sockHandle, $data, 1024, MSG_PEEK);
if($res === 0){
return false;
}else{
return true;
}
}
The important part here is the MSG_PEEK stops any pending messages from being cleared, and the "#" mutes errors if the socket is ok, but no messages are pending.
For the full article, it's available here:
http://www.bracketbrotherhood.com/remote-disconnections-php-non-blocking-server-sockets/programming-and-development/
Regards,
Phil,
Not sure if it's the same now, but a long time ago I ran into php not realizing the connection was aborted until it actually tried to write or flush its output buffers. See php's flush() and ob_flush(); I didn't need to actually write anything to output, just flushing empty buffers was enough to make it check.
I would imagine the webserver(s) and other stuff in front of php could affect this behavior.
You probably need to have already called ignore_user_abort(true); otherwise php will probably stop execution on the flush() call(default behavior is to stop when it realizes the connection is gone), so your if statement will never get executed.
print
"black hole";
flush();
if(connection_aborted()!=0){
// You would think this works but it does not.
}
Actually, you wouldn't think that that would work, because it would require the php script to get to that point in the script. If you wrote it at the end, then the script must run its course.
I would suggest instead:
for($i=0;$i<10;$i++){
echo ' '; ## echo "\0"; might also work
flush();
if(connection_aborted()!=0){
// You would think this works but maybe it will now.
die();
}
sleep(1); # the sleep should come after the check
}
Give it a try. Clearly you are trying to sleep for 10 seconds and then kill the script... in all cases that script will run for 10 seconds.
I am writing a Java applet that downloads images from a web server and displays them to the user. It works fine in Java 1.6.0_3 and later, but on older versions it will completely crash the process about once every 20 page views. There are no error messages in the Java console, because the process is completely frozen. I've waited for almost 15 minutes sometimes, but it never un-freezes.
I added a debug message after every line of code, and determined that the line that is causing the crash is this: InputStream data = urlConn.getInputStream().
urlConn is a URLConnection object that is pointed at the image I want to load. I've tried every combination of options that I can think of, but nothing helps. I haven't been able to find anything in the Java bug database or the release notes for 1.6.0_3.
Has anyone encountered this problem before? Any idea how to fix it?
To determine if it really is the whole JVM process that's frozen, or something else:
(1) get a java stack dump (sigquit/ctrl-break/jstack)
(2) have another background thread doing something you can observe; does it stop?
(3) check if another process (browser/etc) can contact server during freeze? (There's a chance the real problem is server connection depletion)
Is it randomly once-in-every-20-fetches (for example, 5% of the time, sometimes the first fetch in the JVM run), or always after about 20 fetches? If the latter, it sounds like something isn't being closed properly.
If on Linux you can use 'netstat -t' or 'lsof' (with certain options or grepped to show only some lines) to see open sockets; if after each fetch, one more is open, and the count never goes down, you're not closing things properly.
If so, calling close() on the stream you get back and/or disconnect() on the HttpUrlConnection after each try may help. (There may also be more severe limits on the number of connections an applet can leave open, so you're hitting this more quickly than you would in a standalone app.)
The fact that it 'works' in later Javas is also suggestive that some sort of automatic cleanup might be happening more effectively/regularly by finalization/GC. It's best to close things up cleanly yourself but you could also try forcing a GC/runFinalization in the earlier Javas showing the problem.
I'm unsure the cause of the problem you are facing, but I use the following code successfully for synchronously loading images from within applets (loads from either jar file or the server):
public Image loadImage(String imageName) {
// get the image
Image image = getImage(getCodeBase(), imageName);
// wait for it to fully load
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(image, 0);
boolean interrupted = false;
try {
tracker.waitForID(0);
} catch (InterruptedException e) {
interrupted = true;
}
int status = tracker.statusID(thisImageTrackerID, false);
if (status != MediaTracker.COMPLETE) {
throw new RuntimeException("Failed to load " + imageName + ", interrupted:" + interrupted + ", status:" + status);
}
return image;
}