add state machine and callbacks

This commit is contained in:
Harald Hoyer 2017-04-26 08:13:25 +02:00 committed by Harald Hoyer
parent 994aa5ac5a
commit 6e7bb3598a
3 changed files with 164 additions and 74 deletions

View file

@ -66,13 +66,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/template/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/tests/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/tests/assets" type="java-test-resource" />
@ -80,6 +73,13 @@
<sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />

View file

@ -323,6 +323,7 @@ public class BluetoothChatService {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private final IConsole mmIConsole;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
@ -341,56 +342,60 @@ public class BluetoothChatService {
mmInStream = tmpIn;
mmOutStream = tmpOut;
mState = STATE_CONNECTED;
mmIConsole = new IConsole(mmInStream, mmOutStream, new IConsole.DataListner() {
@Override
public void onData(IConsole.Data data) {
Log.i(TAG, "mConnectedThread: " + data.toString());
/* print */
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[5];
int bytes;
int i = 0;
@Override
public void onError(Exception e) {
Log.e(TAG, "mConnectedThread Error: ", e);
// Keep listening to the InputStream while connected
while (mState == STATE_CONNECTED && i < 100) {
try {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
/* pass */;
if (e instanceof IOException)
connectionLost();
}
i++;
this.write(IConsole.PING);
// Read from the InputStream
bytes = mmInStream.read(buffer);
if (bytes > 0) {
String hexbuf = IConsole.byteArrayToHex(Arrays.copyOfRange(buffer, 0, bytes)) + '\n';
}, new IConsole.DebugListner() {
@Override
public void onRead(byte[] buffer) {
if (buffer.length > 0) {
String hexbuf = IConsole.byteArrayToHex(Arrays.copyOfRange(buffer, 0, buffer.length)) + '\n';
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_READ, hexbuf.length(), -1, hexbuf.getBytes())
.sendToTarget();
}
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
@Override
public void onWrite(byte[] buffer) {
String hexbuf = IConsole.byteArrayToHex(buffer) + '\n';
// Share the sent message back to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, hexbuf.getBytes())
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
});
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
while (mState == STATE_CONNECTED) {
if (!mmIConsole.processIO())
break;
}
}
public boolean setLevel(int level) {
return mmIConsole.setLevel(level);
}
public void cancel() {
mmIConsole.stop();
try {
mmSocket.close();
} catch (IOException e) {

View file

@ -1,42 +1,127 @@
package org.surfsite.iconsole;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by harald on 25.04.17.
*/
public class IConsole {
public static final byte[] PING = {(byte) 0xf0, (byte) 0xa0, (byte) 0x01, (byte) 0x01, (byte) 0x92 };
/*
INIT_A0 = struct.pack('BBBBB', 0xf0, 0xa0, 0x02, 0x02, 0x94)
PING = struct.pack('BBBBB', 0xf0, 0xa0, 0x01, 0x01, 0x92)
PONG = struct.pack('BBBBB', 0xf0, 0xb0, 0x01, 0x01, 0xa2)
STATUS = struct.pack('BBBBB', 0xf0, 0xa1, 0x01, 0x01, 0x93)
INIT_A3 = struct.pack('BBBBBB', 0xf0, 0xa3, 0x01, 0x01, 0x01, 0x96)
INIT_A4 = struct.pack('BBBBBBBBBBBBBBB', 0xf0, 0xa4, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xa0)
START = struct.pack('BBBBBB', 0xf0, 0xa5, 0x01, 0x01, 0x02, 0x99)
STOP = struct.pack('BBBBBB', 0xf0, 0xa5, 0x01, 0x01, 0x04, 0x9b)
READ = struct.pack('BBBBB', 0xf0, 0xa2, 0x01, 0x01, 0x94)
*/
public static final byte[] INIT_A0 = {(byte) 0xf0, (byte) 0xa0, 0x02, 0x02, (byte) 0x94};
public static final byte[] PONG = {(byte) 0xf0, (byte) 0xb0, 0x01, 0x01, (byte) 0xa2};
public static final byte[] STATUS = {(byte) 0xf0, (byte) 0xa1, 0x01, 0x01, (byte) 0x93};
public static final byte[] INIT_A3 = {(byte) 0xf0, (byte) 0xa3, 0x01, 0x01, 0x01, (byte) 0x96};
public static final byte[] INIT_A4 = {(byte) 0xf0, (byte) 0xa4, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, (byte) 0xa0};
public static final byte[] START = {(byte) 0xf0, (byte) 0xa5, 0x01, 0x01, 0x02, (byte) 0x99};
public static final byte[] STOP = {(byte) 0xf0, (byte) 0xa5, 0x01, 0x01, 0x04, (byte) 0x9b};
public static final byte[] READ = {(byte) 0xf0, (byte) 0xa2, 0x01, 0x01, (byte) 0x94};
public static final byte[] SETLEVEL = {(byte) 0xf0, (byte) 0xa6, 0x01, 0x01, 0x01, (byte)((0xf0+0xa6+3) & 0xFF)};
/*
def __init__(self, got):
gota = struct.unpack('BBBBBBBBBBBBBBBBBBBBB', got)
self.time_str = "%02d:%02d:%02d:%02d" % (gota[2]-1, gota[3]-1, gota[4]-1, gota[5]-1)
self.speed = ((100*(gota[6]-1) + gota[7] -1) / 10.0)
self.speed_str = "V: % 3.1f km/h" % self.speed
self.rpm = ((100*(gota[8]-1) + gota[9] -1))
self.rpm_str = "% 3d RPM" % self.rpm
self.distance = ((100*(gota[10]-1) + gota[11] -1) / 10.0)
self.distance_str = "D: % 3.1f km" % self.distance
self.calories = ((100*(gota[12]-1) + gota[13] -1))
self.calories_str = "% 3d kcal" % self.calories
self.hf = ((100*(gota[14]-1) + gota[15] -1))
self.hf_str = "HF % 3d" % self.hf
self.power = ((100*(gota[16]-1) + gota[17] -1) / 10.0)
self.power_str = "% 3.1f W" % self.power
self.lvl = gota[18] -1
self.lvl_str = "L: %d" % self.lvl
*/
private enum State {
BEGIN,
PING,
A0,
A1,
A3,
A4,
START,
STOP,
READ,
SETLEVEL,
}
private State mCurrentState;
private State mNextState;
private int mSetLevel;
private final InputStream mInputStream;
private final OutputStream mOutputStream;
private final DataListner mDataListner;
private final DebugListner mDebugListner;
public IConsole(InputStream inputStream, OutputStream outputStream, DataListner dataListner, DebugListner debugListner) {
this.mInputStream = inputStream;
this.mOutputStream = outputStream;
this.mDataListner = dataListner;
this.mDebugListner = debugListner;
this.mCurrentState = State.BEGIN;
this.mNextState = State.PING;
this.mSetLevel = 1;
}
public class Data {
long mTime; // in seconds
int mSpeed10;
int mRPM;
int mDistance10;
int mCalories;
int mHF;
int mPower10;
int mLevel;
public Data(long mTime, int mSpeed10, int mRPM, int mDistance10, int mCalories, int mHF, int mPower10, int mLevel) {
this.mTime = mTime;
this.mSpeed10 = mSpeed10;
this.mRPM = mRPM;
this.mDistance10 = mDistance10;
this.mCalories = mCalories;
this.mHF = mHF;
this.mPower10 = mPower10;
this.mLevel = mLevel;
}
public Data(byte[] bytes) {
this.mTime = (((bytes[2]-1) * 24 + bytes[3]-1) * 60 + bytes[4]-1) * 60 + bytes[5]-1 ;
this.mSpeed10 = 100 * (bytes[ 6] - 1) + bytes[ 7] - 1;
this.mRPM = 100 * (bytes[ 8] - 1) + bytes[ 9] - 1;
this.mDistance10 = 100 * (bytes[10] - 1) + bytes[11] - 1;
this.mCalories = 100 * (bytes[12] - 1) + bytes[13] - 1;
this.mHF = 100 * (bytes[14] - 1) + bytes[15] - 1;
this.mPower10 = 100 * (bytes[16] - 1) + bytes[17] - 1;
this.mLevel = bytes[18] -1;
}
}
public interface DataListner {
void onData(Data data);
void onError(Exception e);
}
public interface DebugListner {
void onRead(byte[] bytes);
void onWrite(byte[] bytes);
}
public boolean processIO() {
synchronized (this) {
Data data = new Data(0, 0, 0, 0, 0, 0, 0, 0);
if (null != mDebugListner) {
mDebugListner.onWrite(PING);
mDebugListner.onRead(PONG);
}
mDataListner.onData(data);
}
return true;
}
public boolean stop() {
return true;
}
public boolean setLevel(int level) {
synchronized (this) {
if (mCurrentState != State.READ)
return false;
this.mCurrentState = State.SETLEVEL;
this.mNextState = State.READ;
this.mSetLevel = level;
}
return true;
}
/*
def send_ack(packet, expect=None, plen=0):