package mobisocial.nfc.legacy;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.UUID;
import mobisocial.bluetooth.InsecureBluetooth;
import mobisocial.ndefexchange.DuplexSocket;
import mobisocial.ndefexchange.NdefExchangeContract;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.nfc.NdefMessage;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.util.Log;
public class NfcBluetoothBridge implements NfcBridge {
private static final String TAG = "nfcserver";
private final UUID mServiceUuid;
private AcceptThread mAcceptThread;
private final NdefExchangeContract mNdefProxy;
private final BluetoothAdapter mBtAdapter;
public NfcBluetoothBridge(NdefExchangeContract ndefProxy, UUID serviceUuid) {
mNdefProxy = ndefProxy;
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
mServiceUuid = serviceUuid;
}
public String getReference() {
return "ndef+bluetooth://" + mBtAdapter.getAddress() + "/" + mServiceUuid;
}
/**
* Starts the listening service
*/
public void start() {
if (mAcceptThread != null)
return;
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
public void stop() {
if (mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
}
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try {
if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD_MR1) {
tmp = mBtAdapter.listenUsingInsecureRfcommWithServiceRecord("NfcHandover", mServiceUuid);
} else {
tmp = InsecureBluetooth.listenUsingRfcommWithServiceRecord(mBtAdapter, "NfcHandover", mServiceUuid, false);
}
} catch (IOException e) {
Log.e(TAG, "Could not open server socket", e);
}
mmServerSocket = tmp;
}
public void run() {
setName("AcceptThread");
DuplexSocket duplexSocket = null;
// Listen to the server socket always
while (true) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
Log.d(TAG, "waiting for client...");
BluetoothSocket socket = mmServerSocket.accept();
Log.d(TAG, "Client connected!");
duplexSocket = new BluetoothDuplexSocket(socket);
} catch (SocketException e) {
} catch (IOException e) {
Log.e(TAG, "accept() failed", e);
break;
}
// If a connection was accepted
if (duplexSocket == null) {
break;
}
new HandoverConnectedThread(duplexSocket, mNdefProxy).start();
}
Log.d(TAG, "END mAcceptThread");
}
public void cancel() {
Log.d(TAG, "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of server failed", e);
}
}
}
static class BluetoothDuplexSocket implements DuplexSocket {
final BluetoothSocket mmSocket;
public BluetoothDuplexSocket(BluetoothSocket socket) throws IOException {
mmSocket = socket;
}
@Override
public void connect() throws IOException {
// already connected
}
@Override
public InputStream getInputStream() throws IOException {
return mmSocket.getInputStream();
}
@Override
public OutputStream getOutputStream() throws IOException {
return mmSocket.getOutputStream();
}
@Override
public void close() throws IOException {
if (mmSocket != null) {
mmSocket.close();
}
}
}
}