Skip to content

Commit c9ebb8b

Browse files
committed
Merge remote-tracking branch 'origin/Dev' into NOL-48
Conflicts: ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java ShimmerDriverPC/src/main/java/com/shimmerresearch/pcDriver/ShimmerPC.java
2 parents f80b76a + 0303c8a commit c9ebb8b

3 files changed

Lines changed: 113 additions & 38 deletions

File tree

ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java

Lines changed: 100 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ public abstract class ShimmerBluetooth extends ShimmerObject implements Serializ
134134
private final static int NUMBER_OF_TX_RETRIES_LIMIT = 0;
135135
private class DUMMY_READ_WAIT_TIME_MS {
136136
private final static int START = 50;
137-
// TODO test to see how low we can set this. Experimentally it was found 200ms is the lowest it can go.
138-
private final static int INITIAL_AFTER_WRITE = 250;
137+
private final static int INITIAL_AFTER_WRITE = 200;
139138
private final static int CHECK_INTERVAL = 100;
140139
private final static int TIMEOUT = 5000;
141140
}
@@ -251,6 +250,7 @@ public String toString() {
251250
transient protected Timer mTimerReadStatus;
252251
transient protected Timer mTimerReadBattStatus; //
253252
transient protected Timer mTimerConnecting;
253+
transient protected Timer mTimerCheckSerialPortClear;
254254

255255
private int mCountDeadConnection = 0;
256256
private boolean mCheckIfConnectionisAlive = false;
@@ -475,7 +475,9 @@ public int getNumCrcBytes() {
475475
//endregion
476476

477477
private int mNumOfMemSetCmds = 0;
478-
478+
479+
private boolean mSerialPortReadTimeout;
480+
479481
public static final int MSG_IDENTIFIER_DATA_PACKET = 2;
480482
public static final int MSG_IDENTIFIER_DEVICE_PAIRED = 8;
481483
public static final int MSG_IDENTIFIER_DEVICE_UNPAIRED = 9;
@@ -617,10 +619,11 @@ private void performDummyRead() {
617619
int totalWaitTimeMs = DUMMY_READ_WAIT_TIME_MS.INITIAL_AFTER_WRITE;
618620
// Allow some time for bytes to come in
619621
threadSleep(DUMMY_READ_WAIT_TIME_MS.INITIAL_AFTER_WRITE);
620-
while (bytesAvailableToBeRead()) {
622+
while (!stop &&bytesAvailableToBeRead()) {
621623
if (totalWaitTimeMs >= DUMMY_READ_WAIT_TIME_MS.TIMEOUT) {
622624
// TODO trigger a disconnect or just allow the first instruction in the instruction stack to trigger it
623625
printLogDataForDebugging("Dummy read timeout");
626+
//TODO send message to app layer to tell it to trigger a disconnect?
624627
break;
625628
}
626629

@@ -1121,7 +1124,7 @@ else if(getHardwareVersion()==HW_ID.SHIMMER_3) {
11211124
initializeShimmer3();
11221125
}
11231126

1124-
stopConnectingTimeoutTimer();
1127+
stopTimerConnectingTimeout();
11251128
startTimerCheckIfAlive();
11261129
}
11271130

@@ -1178,24 +1181,32 @@ private ObjectCluster processSystemTimestampPlot(ObjectCluster objectCluster) {
11781181
*
11791182
*/
11801183
private void clearSerialBuffer() {
1184+
startTimerCheckForSerialPortClear();
1185+
11811186
List<Byte> buffer = new ArrayList<Byte>();
1182-
while (availableBytes()!=0){
1187+
while (availableBytes() != 0) {
11831188
// int available = availableBytes();
1184-
if (bytesAvailableToBeRead()){
1185-
//JC: not working well on android
1186-
//byte[] buffer = readBytes(availableBytes());
1189+
if (bytesAvailableToBeRead()) {
1190+
// JC: not working well on android
1191+
// byte[] buffer = readBytes(availableBytes());
11871192
byte[] tb = readBytes(1);
1188-
if(tb!=null){
1193+
if (tb != null) {
11891194
buffer.add(tb[0]);
11901195
}
1196+
1197+
if (mSerialPortReadTimeout) {
1198+
break;
1199+
}
11911200
}
1192-
}
1193-
1194-
if(buffer.size()>0){
1201+
}
1202+
1203+
if (buffer.size() > 0) {
11951204
byte[] newBuf = ArrayUtils.toPrimitive(buffer.toArray(new Byte[buffer.size()]));
11961205
String msg = "Clearing Buffer:\t\t" + UtilShimmer.bytesToHexStringWithSpacesFormatted(newBuf);
11971206
printLogDataForDebugging(msg);
11981207
}
1208+
1209+
stopTimerCheckForSerialPortClear();
11991210
}
12001211

12011212
/**
@@ -1241,7 +1252,12 @@ private void clearSingleDataPacketFromBuffers(byte[] bufferTemp, int packetSize)
12411252
// consolePrintLn(Integer.toString(bufferTemp[mPacketSize+2]));
12421253
if(mEnablePCTimeStamps) {
12431254
for (int i=0;i<packetSize;i++){
1244-
mListofPCTimeStamps.remove(0);
1255+
try {
1256+
mListofPCTimeStamps.remove(0);
1257+
} catch (Exception e) {
1258+
/* Catch random IndexOutOfBoundsException that occur */
1259+
consolePrintException(e.getMessage(), e.getStackTrace());
1260+
}
12451261
}
12461262
}
12471263
}
@@ -2788,23 +2804,31 @@ public void stopAllTimers(){
27882804
stopTimerCheckAlive();
27892805
stopTimerCheckForAckOrResp();
27902806
stopTimerReadBattStatus();
2791-
stopConnectingTimeoutTimer();
2807+
stopTimerConnectingTimeout();
27922808
}
27932809

27942810
public void stopTimerCheckForAckOrResp(){
27952811
//Terminate the timer thread
27962812
if(mTimerCheckForAckOrResp!=null){
2797-
mTimerCheckForAckOrResp.cancel();
2798-
mTimerCheckForAckOrResp.purge();
2813+
try {
2814+
mTimerCheckForAckOrResp.cancel();
2815+
mTimerCheckForAckOrResp.purge();
2816+
} catch (NullPointerException npe) {
2817+
npe.printStackTrace();
2818+
}
27992819
mTimerCheckForAckOrResp = null;
28002820
}
28012821
}
28022822

28032823
public synchronized void startTimerCheckForAckOrResp(int seconds) {
28042824
//public synchronized void responseTimer(int seconds) {
28052825
if(mTimerCheckForAckOrResp!=null) {
2806-
mTimerCheckForAckOrResp.cancel();
2807-
mTimerCheckForAckOrResp.purge();
2826+
try {
2827+
mTimerCheckForAckOrResp.cancel();
2828+
mTimerCheckForAckOrResp.purge();
2829+
} catch (NullPointerException npe) {
2830+
npe.printStackTrace();
2831+
}
28082832
mTimerCheckForAckOrResp = null;
28092833
}
28102834
printLogDataForDebugging("Waiting for ack/response for command:\t" + btCommandToString(mCurrentCommand));
@@ -2951,8 +2975,12 @@ public void startTimerReadStatus(){
29512975

29522976
public void stopTimerReadStatus(){
29532977
if(mTimerReadStatus!=null){
2954-
mTimerReadStatus.cancel();
2955-
mTimerReadStatus.purge();
2978+
try {
2979+
mTimerReadStatus.cancel();
2980+
mTimerReadStatus.purge();
2981+
} catch (NullPointerException npe) {
2982+
npe.printStackTrace();
2983+
}
29562984
mTimerReadStatus = null;
29572985
}
29582986
}
@@ -2987,8 +3015,12 @@ public void startTimerCheckIfAlive(){
29873015

29883016
public void stopTimerCheckAlive(){
29893017
if(mTimerCheckAlive!=null){
2990-
mTimerCheckAlive.cancel();
2991-
mTimerCheckAlive.purge();
3018+
try {
3019+
mTimerCheckAlive.cancel();
3020+
mTimerCheckAlive.purge();
3021+
} catch (NullPointerException npe) {
3022+
npe.printStackTrace();
3023+
}
29923024
mTimerCheckAlive = null;
29933025
}
29943026
}
@@ -3076,13 +3108,13 @@ public void restartTimersIfNull() {
30763108
}
30773109
}
30783110

3079-
public void startConnectingTimeoutTimer() {
3111+
public void startTimerConnectingTimeout() {
30803112
mTimerConnecting = new Timer();
30813113
mTimerConnecting.schedule(new connectingTimeoutTask(), LiteProtocol.TIMER_CONNECTING_TIMEOUT);
30823114
consolePrintLn("Started connecting timer...");
30833115
}
30843116

3085-
public void stopConnectingTimeoutTimer() {
3117+
public void stopTimerConnectingTimeout() {
30863118
if(mTimerConnecting != null) {
30873119
consolePrintLn("Stopped connecting timer...");
30883120
try {
@@ -3101,12 +3133,54 @@ public void run() {
31013133
if(mBluetoothRadioState == BT_STATE.CONNECTING)
31023134
{
31033135
connectionLost();
3104-
stopConnectingTimeoutTimer();
3136+
stopTimerConnectingTimeout();
31053137
consolePrintLn("Connecting timer timed out, connection lost");
31063138
}
31073139
}
31083140
}
31093141

3142+
public void stopTimerCheckForSerialPortClear(){
3143+
//Terminate the timer thread
3144+
if(mTimerCheckSerialPortClear!=null){
3145+
try {
3146+
mTimerCheckSerialPortClear.cancel();
3147+
mTimerCheckSerialPortClear.purge();
3148+
} catch (NullPointerException npe) {
3149+
npe.printStackTrace();
3150+
}
3151+
3152+
mTimerCheckSerialPortClear = null;
3153+
}
3154+
}
3155+
3156+
public synchronized void startTimerCheckForSerialPortClear() {
3157+
if(mTimerCheckSerialPortClear!=null) {
3158+
try {
3159+
mTimerCheckSerialPortClear.cancel();
3160+
mTimerCheckSerialPortClear.purge();
3161+
} catch (NullPointerException npe) {
3162+
npe.printStackTrace();
3163+
}
3164+
mTimerCheckSerialPortClear = null;
3165+
}
3166+
mSerialPortReadTimeout = false;
3167+
printLogDataForDebugging("Waiting for serial port to clear");
3168+
mTimerCheckSerialPortClear = new Timer("Shimmer_" + getMacIdParsed() + "_TimerCheckForSerialPortClear");
3169+
mTimerCheckSerialPortClear.schedule(new checkForSerialPortClear(), 5000);
3170+
}
3171+
3172+
/** Handles command response timeout
3173+
*
3174+
*/
3175+
class checkForSerialPortClear extends TimerTask {
3176+
@Override
3177+
public void run() {
3178+
System.out.println("Timeout while trying to clear buffer");
3179+
mSerialPortReadTimeout = true;
3180+
connectionLost();
3181+
}
3182+
}
3183+
31103184
//endregion --------- TIMERS ---------
31113185

31123186

ShimmerDriver/src/test/java/com/shimmerresearch/algorithms/API_00002_Filters.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public class API_00002_Filters {
2424

2525
private static final boolean REPLACE_REFERENCE_CSVS = false;
2626

27+
private static final String UNIT_TEST_FILES_PATH = System.getenv("USERPROFILE") + "/Shimmer Research Ltd/Shimmer - Shimmer/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/";
28+
2729
/**
2830
* Passes invalid configuration into the filter initialisation in order to throw an error.
2931
*/
@@ -48,8 +50,8 @@ public void Test_002_LowPass() {
4850
double[] cornerFrequency = { 10 };
4951
int nTaps = 200;
5052

51-
String sourceCsv = "S:/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/WhiteNoise_001.csv";
52-
String referenceCsv = "S:/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/Reference/" + testId + ".csv";
53+
String sourceCsv = UNIT_TEST_FILES_PATH + "WhiteNoise_001.csv";
54+
String referenceCsv = UNIT_TEST_FILES_PATH + "Reference/" + testId + ".csv";
5355

5456
runTestCommon(testId, sourceCsv, referenceCsv, filterType, samplingRate, cornerFrequency, nTaps);
5557
}
@@ -65,8 +67,8 @@ public void Test_003_HighPass() {
6567
double[] cornerFrequency = { 400 };
6668
int nTaps = 200;
6769

68-
String sourceCsv = "S:/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/WhiteNoise_001.csv";
69-
String referenceCsv = "S:/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/Reference/" + testId + ".csv";
70+
String sourceCsv = UNIT_TEST_FILES_PATH + "WhiteNoise_001.csv";
71+
String referenceCsv = UNIT_TEST_FILES_PATH + "Reference/" + testId + ".csv";
7072

7173
runTestCommon(testId, sourceCsv, referenceCsv, filterType, samplingRate, cornerFrequency, nTaps);
7274
}
@@ -82,8 +84,8 @@ public void Test_004_BandStop() {
8284
double[] cornerFrequency = { 100, 400 };
8385
int nTaps = 200;
8486

85-
String sourceCsv = "S:/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/WhiteNoise_001.csv";
86-
String referenceCsv = "S:/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/Reference/" + testId + ".csv";
87+
String sourceCsv = UNIT_TEST_FILES_PATH + "WhiteNoise_001.csv";
88+
String referenceCsv = UNIT_TEST_FILES_PATH + "Reference/" + testId + ".csv";
8789

8890
runTestCommon(testId, sourceCsv, referenceCsv, filterType, samplingRate, cornerFrequency, nTaps);
8991
}
@@ -99,8 +101,8 @@ public void Test_005_BandPass() {
99101
double[] cornerFrequencies = { 100, 400 };
100102
int nTaps = 200;
101103

102-
String sourceCsv = "S:/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/WhiteNoise_001.csv";
103-
String referenceCsv = "S:/Applications Team/Resources/Data Repository/JUnitTests/Shimmer-Java-Android-API/API_00002_Filters/Reference/" + testId + ".csv";
104+
String sourceCsv = UNIT_TEST_FILES_PATH + "WhiteNoise_001.csv";
105+
String referenceCsv = UNIT_TEST_FILES_PATH + "Reference/" + testId + ".csv";
104106

105107
runTestCommon(testId, sourceCsv, referenceCsv, filterType, samplingRate, cornerFrequencies, nTaps);
106108
}

ShimmerDriverPC/src/main/java/com/shimmerresearch/pcDriver/ShimmerPC.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ public void run(){
349349
setBluetoothRadioState(BT_STATE.CONNECTING);
350350

351351
// mMyBluetoothAddress = address;
352-
startConnectingTimeoutTimer();
352+
startTimerConnectingTimeout();
353353

354354
setIamAlive(false);
355355
getListofInstructions().clear();
@@ -603,7 +603,7 @@ private void closeConnection(){
603603
mIOThread.stop = true;
604604

605605
// Closing serial port before before thread is finished stopping throws an error so waiting here
606-
while(mIOThread.isAlive());
606+
while(mIOThread != null && mIOThread.isAlive());
607607

608608
mIOThread = null;
609609

@@ -622,10 +622,9 @@ private void closeConnection(){
622622
mSerialPort.purgePort(2);
623623
mSerialPort.closePort();
624624
}
625-
626625
}
627626
mSerialPort = null;
628-
} catch (SerialPortException ex) {
627+
} catch (Exception ex) {
629628
consolePrintException(ex.getMessage(), ex.getStackTrace());
630629
setBluetoothRadioState(BT_STATE.DISCONNECTED);
631630
}

0 commit comments

Comments
 (0)