package mobisocial.nfc.legacy;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.nfc.NdefMessage;
import android.util.Log;
import mobisocial.ndefexchange.DuplexSocket;
import mobisocial.ndefexchange.NdefExchangeContract;
/**
* Runs a thread during a connection handover with a remote device over a
* {@see DuplexSocket}, transmitting the given Ndef message.
*/
class HandoverConnectedThread extends Thread {
private static final String TAG = "NdefHandover";
public static final byte HANDOVER_VERSION = 0x19;
private final DuplexSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private final NdefExchangeContract mmNdefProxy;
private boolean mmIsWriteDone = false;
private boolean mmIsReadDone = false;
public HandoverConnectedThread(DuplexSocket socket, NdefExchangeContract ndefProxy) {
mmNdefProxy = ndefProxy;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
socket.connect();
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
try {
if (mmInStream == null || mmOutStream == null) {
return;
}
// Read on this thread, write on a new one.
new SendNdefThread().start();
DataInputStream dataIn = new DataInputStream(mmInStream);
byte version = (byte) dataIn.readByte();
if (version != HANDOVER_VERSION) {
throw new Exception("Bad handover protocol version.");
}
int length = dataIn.readInt();
if (length > 0) {
byte[] ndefBytes = new byte[length];
int read = 0;
while (read < length) {
read += dataIn.read(ndefBytes, read, (length - read));
}
NdefMessage ndef = new NdefMessage(ndefBytes);
mmNdefProxy.handleNdef(new NdefMessage[] {ndef});
}
} catch (Exception e) {
Log.e(TAG, "Failed to issue handover.", e);
} finally {
synchronized(HandoverConnectedThread.this) {
mmIsReadDone = true;
if (mmIsWriteDone) {
cancel();
}
}
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {}
}
private class SendNdefThread extends Thread {
@Override
public void run() {
try {
NdefMessage outbound = mmNdefProxy.getForegroundNdefMessage();
DataOutputStream dataOut = new DataOutputStream(mmOutStream);
dataOut.writeByte(HANDOVER_VERSION);
if (outbound != null) {
byte[] ndefBytes = outbound.toByteArray();
dataOut.writeInt(ndefBytes.length);
dataOut.write(ndefBytes);
} else {
dataOut.writeInt(0);
}
dataOut.flush();
} catch (IOException e) {
Log.e(TAG, "Error writing to socket", e);
} finally {
synchronized(HandoverConnectedThread.this) {
mmIsWriteDone = true;
if (mmIsReadDone) {
cancel();
}
}
}
}
}
}