/*
CanZE
Take a closer look at your ZE car
Copyright (C) 2015 - The CanZE Team
http://canze.fisch.lu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package lu.fisch.canze.devices;
import java.io.IOException;
import java.util.Calendar;
import lu.fisch.canze.activities.MainActivity;
import lu.fisch.canze.actors.Field;
import lu.fisch.canze.actors.Frame;
import lu.fisch.canze.actors.Message;
import lu.fisch.canze.bluetooth.BluetoothManager;
/**
* Created by robertfisch on 07.09.2015.
*/
public class BobDue extends Device {
// *** needed by the "reader" part
//private String buffer = "";
//private final String separator = "\n";
private static final int WRONG_THRESHOLD = 20;
// define the timeout we may wait to get an answer
private static final int TIMEOUT = 500;
// define End Of Message for this type of reader
private static final char EOM = '\n';
// the actual filter
//private int fieldIndex = 0;
// the thread that polls the data to the stack
public void join() throws InterruptedException {
pollerThread.join();
}
@Override
public void registerFilter(int frameId) {
String filter = Integer.toHexString(frameId);
if(BluetoothManager.getInstance().isConnected())
BluetoothManager.getInstance().write("f" + filter + "\n");
else
MainActivity.debug("BobDue.registerFilter " + filter + " failed because connectedBluetoothThread is NULL");
}
@Override
public void unregisterFilter(int frameId) {
String filter = Integer.toHexString(frameId);
if(BluetoothManager.getInstance().isConnected())
BluetoothManager.getInstance().write("r" + filter + "\n");
else
MainActivity.debug("BobDue.unregisterFilter " + filter + " failed because connectedBluetoothThread is NULL");
}
// send a command and wait for an answer
private String sendAndWaitForAnswer(String command, int waitMillis)
{
// empty incoming buffer
// just make sure there is no previous response
try {
while(BluetoothManager.getInstance().available()>0)
{
BluetoothManager.getInstance().read();
}
} catch (IOException e) {
// ignore
}
// send the command
if(command!=null)
// prefix fir EOM to make sure the previous command is done!
BluetoothManager.getInstance().write("\r\n"+command + "\r\n");
//MainActivity.debug("Send > "+command);
// wait if needed
if(waitMillis>0)
try {
Thread.sleep(waitMillis);
} catch (InterruptedException e) {
e.printStackTrace();
}
// init the buffer
boolean stop = false;
String readBuffer = "";
// wait for answer
long start = Calendar.getInstance().getTimeInMillis();
while(!stop && Calendar.getInstance().getTimeInMillis()-start<TIMEOUT)
{
//MainActivity.debug("Delta = "+(Calendar.getInstance().getTimeInMillis()-start));
try {
// read a byte
if(BluetoothManager.getInstance().available()>0) {
//MainActivity.debug("Reading ...");
int data = BluetoothManager.getInstance().read();
//MainActivity.debug("... done");
// if it is a real one
if (data != -1) {
// convert it to a character
char ch = (char) data;
// add it to the readBuffer
readBuffer += ch;
// stop if we reached the end or if no more data is available
if ((ch == EOM || BluetoothManager.getInstance().available() <= 0) &&
!readBuffer.trim().isEmpty()) stop = true;
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
//MainActivity.debug("Recv < "+readBuffer);
return readBuffer;
}
private int wrongCount = 0;
@Override
public void clearFields() {
super.clearFields();
//fieldIndex =0;
}
@Override
public Message requestFreeFrame(Frame frame) {
// send the command and wait fir an answer, no delay
String data = sendAndWaitForAnswer("g" + frame.getHexId(), 0);
// handle empty answer
if(data.trim().isEmpty()) wrongCount++;
if(wrongCount>WRONG_THRESHOLD) {
wrongCount=0;
(new Thread(new Runnable() {
@Override
public void run() {
MainActivity.getInstance().stopBluetooth(false);
MainActivity.getInstance().reloadBluetooth(false);
}
})).start();
}
return responseToMessage(frame,data);
}
@Override
public Message requestIsoTpFrame(Frame frame) {
// build the command string to send to the remote device
String command = "i" + frame.getHexId() + "," + frame.getRequestId() + "," + frame.getResponseId();
String data = sendAndWaitForAnswer(command, 0);
// handle empty answer
if(data.trim().isEmpty()) wrongCount++;
if(wrongCount>WRONG_THRESHOLD) {
wrongCount=0;
(new Thread(new Runnable() {
@Override
public void run() {
MainActivity.getInstance().stopBluetooth(false);
MainActivity.getInstance().reloadBluetooth(false);
}
})).start();
}
// send and wait for an answer, no delay
return responseToMessage(frame,data);
}
private Message responseToMessage(Frame frame, String text)
{
// split up the fields
String[] pieces = text.trim().split(",");
if(pieces.length>1)
return new Message(frame, pieces[1].trim(), false);
else
{
MainActivity.debug("BobDue: Got > "+text.trim());
return new Message(frame, "-E-Unexpected result", true);
}
}
@Override
public boolean initDevice(int toughness) {
lastInitProblem = "";
return true;
}
@Override
protected boolean initDevice(int toughness, int retries) {
return true;
}
}