package org.oobd.ui.android;
//openXC imports
import android.content.Context;
import android.util.Log;
//import com.google.common.base.Objects;
//import com.google.protobuf.GeneratedMessage.*;
import com.openxc.measurements.UnrecognizedMeasurementTypeException;
import com.openxc.remote.RawMeasurement;
import com.openxc.sources.ContextualVehicleDataSource;
import com.openxc.sources.SourceCallback;
/**
* A openXC vehicle data source that pushes OOBD data to openXC.
*
* data transfer will not begin until a callback is set, either via a
* constructor or the
* {@link com.openxc.sources.BaseVehicleDataSource#setCallback(SourceCallback)}
* function.
*/
class OOBDVehicleDataSource extends ContextualVehicleDataSource implements
Runnable {
private static final String TAG = "OOBDVehicleDataSource";
private boolean mTraceValid = false;
private long mFirstTimestamp = 0;
private boolean mRunning = true;
private String line = "";
final Object synchLock = new Object();
/**
* Construct a oobd data source with the given context and callback
*
* If the callback is not null, transfer will begin immediately.
*
* @param callback
* An object implementing the SourceCallback interface that
* should receive data as it is received and parsed.
*/
public OOBDVehicleDataSource(SourceCallback callback, Context context) {
super(callback, context);
Log.d(TAG, "Starting new OOBD openXC data source");
new Thread(this).start();
}
/**
* Consider the trace source "connected" if it's running and at least 1
* measurement was parsed successfully from the file.
*
* This will catch errors e.g. if the trace is totally corrupted, but it
* won't give you any indication if it is partially corrupted.
*/
@Override
public boolean isConnected() {
return mRunning && mTraceValid;
}
/**
* Stop trace file playback and the playback thread.
*/
public void stop() {
super.stop();
Log.d(TAG, "Stopping trace playback");
mRunning = false;
synchronized (synchLock) {
line = "";
synchLock.notify();
}
}
/**
* transfer line.
*/
public void sendJsonString2openXC(String json) {
if (json != "") {
RawMeasurement measurement;
try {
measurement = new RawMeasurement(json);
if (measurement != null && !measurement.isTimestamped()) {
Log.w(TAG, "A trace line was missing a timestamp: " + json);
} else {
measurement.untimestamp();
if (!mTraceValid) {
connected();
mTraceValid = true;
}
handleMessage(measurement);
}
} catch (UnrecognizedMeasurementTypeException e) {
Log.w(TAG, "A trace line was not in the expected " + "format: "
+ json);
}
}
}
/**
* While running, continuously read from the trace file and send messages to
* the callback.
*
* If the callback is not set, this function will exit immediately and the
* thread will die a quick death.
*/
public void run() {
Log.d(TAG, "Starting oobd -> openXC transfer");
while (mRunning) {
try {
synchronized (synchLock) {
synchLock.wait();
}
} catch (InterruptedException ex) {
}
if (line != "") {
RawMeasurement measurement;
try {
measurement = new RawMeasurement(line);
} catch (UnrecognizedMeasurementTypeException e) {
Log.w(TAG, "A trace line was not in the expected "
+ "format: " + line);
continue;
}
if (measurement != null && !measurement.isTimestamped()) {
Log.w(TAG, "A trace line was missing a timestamp: " + line);
continue;
}
measurement.untimestamp();
if (!mTraceValid) {
connected();
mTraceValid = true;
}
handleMessage(measurement);
}
disconnected();
Log.d(TAG, "Restarting OOBD openXC transfer");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
disconnected();
mRunning = false;
Log.d(TAG, "OOBD -> openXC transfer is finished");
}
public void sendJSONString(String jsonString) {
sendJsonString2openXC(jsonString);
/*
try {
synchronized (synchLock) {
line = jsonString;
synchLock.notify();
}
} catch (Exception ex) {
}
*/
}
protected String getTag() {
return TAG;
}
}