package dk.silverbullet.telemed.device.vitalographlungmonitor;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import dk.silverbullet.telemed.device.DeviceInitialisationException;
import dk.silverbullet.telemed.device.bluetooth.BluetoothConnector;
import dk.silverbullet.telemed.device.vitalographlungmonitor.packet.PacketReceiver;
import dk.silverbullet.telemed.device.vitalographlungmonitor.packet.VitalographPacket;
import dk.silverbullet.telemed.utils.Util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import java.util.regex.Pattern;
public class VitalographLungMonitorController extends Thread implements PacketReceiver, LungMonitorController {
private static final String TAG = Util.getTag(VitalographLungMonitorController.class);
private static final UUID SERIAL_SERVICE_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final BluetoothConnector connector = new BluetoothConnector();
private final BluetoothDevice device;
private final Object writeSemaphore = new Object();
private volatile boolean running;
private BluetoothSocket socket;
private InputStream inputStream;
private OutputStream outputStream;
private LungMonitorPacketCollector packetCollector;
private LungMonitorListener listener;
public static LungMonitorController create(LungMonitorListener listener) throws DeviceInitialisationException {
return new VitalographLungMonitorController(listener);
}
public VitalographLungMonitorController(LungMonitorListener listener) throws DeviceInitialisationException {
this.listener = listener;
connector.initiate();
device = connector.getDevice(Pattern.compile("LUNG_.*"), "10:00:E8:");
start();
}
@Override
public void close() {
running = false;
interrupt();
closeBluetoothSocket();
}
@Override
public void run() {
running = true;
packetCollector = new LungMonitorPacketCollector();
packetCollector.setListener(this);
try {
while (running) {
sleep(3000);
Log.d(TAG, "Connecting...");
try {
socket = device.createInsecureRfcommSocketToServiceRecord(SERIAL_SERVICE_UUID);
if (socket == null) {
throw new IOException("NullSocket!");
}
socket.connect();
inputStream = socket.getInputStream();
listener.connected();
Log.d(TAG, "Read is working, now open output!");
synchronized (writeSemaphore) {
outputStream = socket.getOutputStream();
writeSemaphore.notify();
}
Log.d(TAG, "Output opened, now start working!");
int read = inputStream.read();
packetCollector.reset();
while (read >= 0 && running) {
packetCollector.receive((byte) read);
read = inputStream.read();
}
} catch (IOException ioe) {
Log.d(TAG, "Reader exception: " + ioe);
} finally {
closeBluetoothSocket();
}
}
} catch (InterruptedException e) {
Log.d(TAG, "Reader thread was interrupted!");
} finally {
Log.d(TAG, "Reader thread stopped!");
running = false;
}
}
private synchronized void closeBluetoothSocket() {
Log.i(TAG, "Closing Bluetooth socket");
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
Log.i(TAG, "Could not close Bluetooth socket", e);
} finally {
socket = null;
}
}
@Override
public void receive(VitalographPacket packet) {
if (packet instanceof FevMeasurementPacket) {
FevMeasurementPacket fevMeasurement = (FevMeasurementPacket) packet;
LungMeasurement measurement = new LungMeasurement(fevMeasurement.getFev1(), fevMeasurement.getFev6(),
fevMeasurement.getFev1Fev6Ratio(), fevMeasurement.getFef2575(), fevMeasurement.isGoodTest(),
fevMeasurement.getSoftwareVersion());
listener.measurementReceived(fevMeasurement.getDeviceId(), measurement);
}
}
@Override
public void error(IOException e) {
listener.temporaryProblem();
}
@Override
public void sendByte(byte b) throws IOException {
synchronized (writeSemaphore) {
if (outputStream == null) {
throw new IllegalStateException("No outputstream");
}
outputStream.write(b);
}
}
}