From 7c6786b729a0c8d60f264b14cb9691150db28c90 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Tue, 25 Nov 2025 11:54:24 +0000 Subject: [PATCH 01/15] DEV-574 #time 1h better byte throwing handling and timestamp fail-safe --- .../bluetooth/ShimmerBluetooth.java | 46 ++++++++++++++----- .../shimmerresearch/driver/ObjectCluster.java | 2 + .../shimmerresearch/driver/ShimmerObject.java | 23 +++++++++- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index ec441ad7f..71347b786 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -715,7 +715,7 @@ else if((mCurrentCommand==GET_FW_VERSION_COMMAND) } threadSleep((int)((Math.random()+.1)*100.0)); writeBytes(insBytes); - printLogDataForDebugging("Command Transmitted: \t\t\t" + btCommandToString(mCurrentCommand) + " " + UtilShimmer.bytesToHexStringWithSpacesFormatted(insBytes)); + printLogDataForDebugging("Command Transmitted: \t\t\t" + btCommandToString(mCurrentCommand) + ", len=" + insBytes.length + " " + UtilShimmer.bytesToHexStringWithSpacesFormatted(insBytes)); //TODO: are the two stops needed here? better to wait for ack from Shimmer if(mCurrentCommand==STOP_STREAMING_COMMAND @@ -880,7 +880,7 @@ private void processNotStreamingWaitForResp() { mWaitForResponse=false; mTransactionCompleted=true; setInstructionStackLock(false); - printLogDataForDebugging("Response Received:\t\t\t" + btCommandToString(responseCommand)); + printLogDataForDebugging("Response Received:\t\t\t" + btCommandToString(responseCommand) + ", len=" + byteBuffer.length + " " + UtilShimmer.bytesToHexStringWithSpacesFormatted(byteBuffer)); // Special case for FW_VERSION_RESPONSE because it // needs to initialize the Shimmer after releasing @@ -939,7 +939,7 @@ protected void processPacket() { && bufferTemp[getPacketSizeWithCrc()+1]==DATA_PACKET){ if (mBtCommsCrcModeCurrent != BT_CRC_MODE.OFF && !checkCrc(bufferTemp, getPacketSize() + 1)) { - discardFirstBufferByte(); + discardBufferBytesToNextPacket(); return; } @@ -1002,8 +1002,8 @@ else if(isSupportedInStreamCmds() && bufferTemp[getPacketSizeWithCrc()+2]==INSTR } } if(mByteArrayOutputStream.size()>getPacketSizeWithCrc()+2){ - printLogDataForDebugging("Unknown packet error (check with JC):\tExpected: " + (getPacketSizeWithCrc()+2) + "bytes but buffer contains " + mByteArrayOutputStream.size() + "bytes"); - discardFirstBufferByte(); //throw the first byte away + printLogDataForDebugging("Unknown packet error: \tExpected: " + (getPacketSizeWithCrc()+2) + "bytes but buffer contains " + mByteArrayOutputStream.size() + "bytes"); + discardBufferBytesToNextPacket(); // Skip to start of next packet } } @@ -1012,7 +1012,7 @@ else if(isSupportedInStreamCmds() && bufferTemp[getPacketSizeWithCrc()+2]==INSTR else { printLogDataForDebugging("Packet syncing problem:\tExpected: " + (getPacketSizeWithCrc()+2) + "bytes. Buffer contains " + mByteArrayOutputStream.size() + "bytes" + "\nBuffer = " + UtilShimmer.bytesToHexStringWithSpacesFormatted(mByteArrayOutputStream.toByteArray())); - discardFirstBufferByte(); //throw the first byte away + discardBufferBytesToNextPacket(); // Skip to start of next packet } } @@ -1052,7 +1052,7 @@ public boolean checkCrc(byte[] bufferTemp, int length) { if (mBtCommsCrcModeCurrent == BT_CRC_MODE.TWO_BYTE_CRC) { // + 2 as this is the location of the CRC's MSB if (bufferTemp[getPacketSize() + 2] != crcCalc[1]) { - discardFirstBufferByte(); + discardBufferBytesToNextPacket(); return false; } } @@ -1190,6 +1190,10 @@ private void buildAndSendMsg(byte[] packet, COMMUNICATION_TYPE fwType, boolean t ObjectCluster objectCluster = null; try { objectCluster = buildMsg(packet, fwType, timeSync, pcTimeStamp); + if(objectCluster.successfullyParsed==false){ + printLogDataForDebugging("Packet timestamp is not contiguous - skipping:\t\t" + UtilShimmer.bytesToHexStringWithSpacesFormatted(packet)); + return; + } objectCluster = systemTimestampPlot.processSystemTimestampPlot(objectCluster); } catch (Exception e) { e.printStackTrace(); @@ -1294,16 +1298,34 @@ protected void clearBuffers() { } /** - * + * Next packet start should begin with DATA_PACKET or ACK_COMMAND_PROCESSED byte so skip to that point */ - protected void discardFirstBufferByte(){ + protected void discardBufferBytesToNextPacket(){ byte[] bTemp = mByteArrayOutputStream.toByteArray(); + + //Find index of first DATA_PACKET or ACK byte within the buffer + int offset = findOffsetOfNextZeroOrFF(bTemp); + //If not found, just skip one byte + offset = (offset == -1) ? 1 : offset; + mByteArrayOutputStream.reset(); - mByteArrayOutputStream.write(bTemp, 1, bTemp.length-1); //this will throw the first byte away + mByteArrayOutputStream.write(bTemp, offset, bTemp.length-offset); //this will throw the first byte away if(mEnablePCTimeStamps) { - mListofPCTimeStamps.remove(0); + for (int i=0;i CONTIGUOUS_TIMESTAMP_TICKS_LIMIT) { + mLastReceivedTimeStampTicks = shimmerTimestampTicks; + objectCluster.successfullyParsed = false; + return objectCluster; //discard packet + } + mLastReceivedTimeStampTicks = shimmerTimestampTicks; + } + parseTimestampShimmer3(fwType, objectCluster, uncalibratedData, uncalibratedDataUnits, calibratedData, calibratedDataUnits, sensorNames, newPacketInt); //OFFSET From 9e495e6f3766875d68681e29c621deee98c62b92 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Tue, 25 Nov 2025 16:13:38 +0000 Subject: [PATCH 02/15] DEV-574 #time 5m ability to disable contiguous time stamp check --- .../main/java/com/shimmerresearch/driver/ShimmerObject.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java index 4b9664850..f5b660a31 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java @@ -494,7 +494,7 @@ public class BTStream { public static final int MAX_NUMBER_OF_SIGNALS = 77;//50; //used to be 11 but now 13 because of the SR30 + 8 for 3d orientation public static final int MAX_INQUIRY_PACKET_SIZE = 47; - public static final int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); // 10 seconds worth of ticks + public static final int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); // 10 seconds worth of ticks. Set to 0 to disable the feature public enum TEST_MODE { MAIN_TEST((byte)0, "Main Test"), @@ -934,7 +934,7 @@ public ObjectCluster buildMsg(byte[] newPacket, COMMUNICATION_TYPE fwType, boole * check help to make sure the time stamp ticks are contiguous before parsing the * packet. */ - if (fwType == COMMUNICATION_TYPE.BLUETOOTH) + if (fwType == COMMUNICATION_TYPE.BLUETOOTH && CONTIGUOUS_TIMESTAMP_TICKS_LIMIT != 0) { double shimmerTimestampTicks = (double)newPacketInt[getSignalIndex(Configuration.Shimmer3.ObjectClusterSensorName.TIMESTAMP)]; if(mLastReceivedTimeStampTicks!=0 && Math.abs(shimmerTimestampTicks - mLastReceivedTimeStampTicks) > CONTIGUOUS_TIMESTAMP_TICKS_LIMIT) { From 61c2fca7ac4fe3f01afa34e6bc9c29b3a33ad590 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 26 Nov 2025 08:37:30 +0000 Subject: [PATCH 03/15] DEV-574 #time 5m more efficient removal of time stamp per byte from list --- .../com/shimmerresearch/bluetooth/ShimmerBluetooth.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index 71347b786..654c9819a 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -1311,10 +1311,8 @@ protected void discardBufferBytesToNextPacket(){ mByteArrayOutputStream.reset(); mByteArrayOutputStream.write(bTemp, offset, bTemp.length-offset); //this will throw the first byte away if(mEnablePCTimeStamps) { - for (int i=0;i Date: Wed, 26 Nov 2025 12:57:39 +0000 Subject: [PATCH 04/15] Update ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../com/shimmerresearch/bluetooth/ShimmerBluetooth.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index 654c9819a..b20f0c9ff 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -1317,9 +1317,9 @@ protected void discardBufferBytesToNextPacket(){ consolePrintLn("Throw Bytes " + UtilShimmer.bytesToHexStringWithSpacesFormatted(Arrays.copyOfRange(bTemp, 0, offset))); } - private static int findOffsetOfNextZeroOrFF(byte[] a) { - for (int i = 1; i < a.length; i++) { - byte b = a[i]; + private static int findOffsetOfNextZeroOrFF(byte[] buffer) { + for (int i = 1; i < buffer.length; i++) { + byte b = buffer[i]; if (b == 0 || b == (byte) 0xFF) return i; } From 831e33266623a4db72cc95f55bc48040476e6ecd Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 26 Nov 2025 12:58:11 +0000 Subject: [PATCH 05/15] Update ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index b20f0c9ff..e4e7db7b8 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -1309,7 +1309,7 @@ protected void discardBufferBytesToNextPacket(){ offset = (offset == -1) ? 1 : offset; mByteArrayOutputStream.reset(); - mByteArrayOutputStream.write(bTemp, offset, bTemp.length-offset); //this will throw the first byte away + mByteArrayOutputStream.write(bTemp, offset, bTemp.length-offset); // discard first 'offset' bytes if(mEnablePCTimeStamps) { // Remove first `offset` elements from the original list (destructive, modifies same list) mListofPCTimeStamps.subList(0, offset).clear(); From 456b1854f917c26f3b425e70cc71e53eb80c8cd8 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 26 Nov 2025 12:58:43 +0000 Subject: [PATCH 06/15] Update ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../main/java/com/shimmerresearch/driver/ObjectCluster.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java index f22d4bf60..66b2a8bad 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java @@ -157,6 +157,10 @@ public enum OBJECTCLUSTER_TYPE{ public int mIndexUncal = 0; public boolean mEnableArraysDataStructure = false; + /** + * Indicates whether the packet was successfully parsed. Set to false when validation checks + * fail (e.g., timestamp contiguity check) to signal that the ObjectCluster should be discarded. + */ public boolean successfullyParsed = true; public class SensorDataPerType { From a21639abb99efaf050ae4fcd53010278bb3bc2b9 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 26 Nov 2025 13:07:34 +0000 Subject: [PATCH 07/15] Update ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/main/java/com/shimmerresearch/driver/ShimmerObject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java index f5b660a31..7473df692 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java @@ -931,7 +931,7 @@ public ObjectCluster buildMsg(byte[] newPacket, COMMUNICATION_TYPE fwType, boole /* * Even with checking for start and stop of packets while parsing and performing * CRC checks, some corrupted packets can still slip through. This is a final - * check help to make sure the time stamp ticks are contiguous before parsing the + * check to help make sure the time stamp ticks are contiguous before parsing the * packet. */ if (fwType == COMMUNICATION_TYPE.BLUETOOTH && CONTIGUOUS_TIMESTAMP_TICKS_LIMIT != 0) From 0d0efd6c254b75af5f26bdde6998461efc52b608 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 26 Nov 2025 13:08:53 +0000 Subject: [PATCH 08/15] Update ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../com/shimmerresearch/bluetooth/ShimmerBluetooth.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index e4e7db7b8..9cf0d90e5 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -1317,6 +1317,12 @@ protected void discardBufferBytesToNextPacket(){ consolePrintLn("Throw Bytes " + UtilShimmer.bytesToHexStringWithSpacesFormatted(Arrays.copyOfRange(bTemp, 0, offset))); } + /** + * Finds the offset/index of the next DATA_PACKET (0x00) or ACK_COMMAND_PROCESSED (0xFF) byte. + * + * @param a byte array to search within + * @return index of the first 0x00 or 0xFF byte found after position 0, or -1 if not found + */ private static int findOffsetOfNextZeroOrFF(byte[] buffer) { for (int i = 1; i < buffer.length; i++) { byte b = buffer[i]; From 322ef02c0ec73f62a3eb8c8bbbfd74484c719870 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 26 Nov 2025 13:11:25 +0000 Subject: [PATCH 09/15] DEV-574 #time 1m minor update from PR --- .../src/main/java/com/shimmerresearch/driver/ShimmerObject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java index 7473df692..40ce34f9a 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java @@ -494,7 +494,7 @@ public class BTStream { public static final int MAX_NUMBER_OF_SIGNALS = 77;//50; //used to be 11 but now 13 because of the SR30 + 8 for 3d orientation public static final int MAX_INQUIRY_PACKET_SIZE = 47; - public static final int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); // 10 seconds worth of ticks. Set to 0 to disable the feature + public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); // 10 seconds worth of ticks. Set to 0 to disable the feature public enum TEST_MODE { MAIN_TEST((byte)0, "Main Test"), From 834c5bc3002dcc89f94a0499108adb12dae90394 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 26 Nov 2025 13:22:42 +0000 Subject: [PATCH 10/15] DEV-574 #time 10m applying PR comments --- .../bluetooth/ShimmerBluetooth.java | 1 + .../shimmerresearch/driver/ShimmerObject.java | 26 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index 9cf0d90e5..6c9435c78 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -2818,6 +2818,7 @@ public void startStreaming() throws ShimmerException { initialiseStreaming(); + super.mLastReceivedTimeStampTicks = 0; mByteArrayOutputStream.reset(); mListofPCTimeStamps.clear(); writeInstruction(START_STREAMING_COMMAND); diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java index 40ce34f9a..c8352e27b 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java @@ -494,7 +494,22 @@ public class BTStream { public static final int MAX_NUMBER_OF_SIGNALS = 77;//50; //used to be 11 but now 13 because of the SR30 + 8 for 3d orientation public static final int MAX_INQUIRY_PACKET_SIZE = 47; - public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); // 10 seconds worth of ticks. Set to 0 to disable the feature + /** + * Maximum allowed gap between consecutive packet timestamps in ticks (10 seconds at 32768 Hz). + * Used to detect corrupted packets that pass CRC checks. + *

+ * Why 10 seconds: Empirically chosen to balance between catching data corruption and allowing for + * occasional transmission delays. This value can be tuned based on expected packet arrival rates. + *

+ * Setting to 0 disables this check entirely. + *

+ * Relationship to timestamp rollover: This value must be less than half the timestamp rollover period + * (i.e., the maximum value before the timestamp counter wraps) to avoid false positives due to rollover. + *

+ * Sampling rate: The value is calculated for a 32768 Hz sampling rate. If a different sampling rate is used, + * this value should be adjusted accordingly (ticks = seconds * sampling rate). + */ + public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); public enum TEST_MODE { MAIN_TEST((byte)0, "Main Test"), @@ -788,7 +803,10 @@ public String toString() { // ---------- GSR end ------------------ - private double mLastReceivedTimeStampTicks = 0; + /** + * Stores the last received timestamp in ticks (for detecting corrupted packets). + */ + protected double mLastReceivedTimeStampTicks = 0; public ObjectCluster setLSLTimeIfAvailable(ObjectCluster ojc) { return ojc; @@ -937,8 +955,8 @@ public ObjectCluster buildMsg(byte[] newPacket, COMMUNICATION_TYPE fwType, boole if (fwType == COMMUNICATION_TYPE.BLUETOOTH && CONTIGUOUS_TIMESTAMP_TICKS_LIMIT != 0) { double shimmerTimestampTicks = (double)newPacketInt[getSignalIndex(Configuration.Shimmer3.ObjectClusterSensorName.TIMESTAMP)]; - if(mLastReceivedTimeStampTicks!=0 && Math.abs(shimmerTimestampTicks - mLastReceivedTimeStampTicks) > CONTIGUOUS_TIMESTAMP_TICKS_LIMIT) { - mLastReceivedTimeStampTicks = shimmerTimestampTicks; + if(mLastReceivedTimeStampTicks!=0 + && Math.abs(shimmerTimestampTicks - mLastReceivedTimeStampTicks) > CONTIGUOUS_TIMESTAMP_TICKS_LIMIT) { objectCluster.successfullyParsed = false; return objectCluster; //discard packet } From db28957a6fd5e43562c6d2bb20598549c52ae36d Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 3 Dec 2025 10:27:52 +0000 Subject: [PATCH 11/15] DEV-574 #time 5m removed contiguous check --- .../bluetooth/ShimmerBluetooth.java | 5 --- .../shimmerresearch/driver/ObjectCluster.java | 6 --- .../shimmerresearch/driver/ShimmerObject.java | 40 ------------------- 3 files changed, 51 deletions(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index 6c9435c78..207c93234 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -1190,10 +1190,6 @@ private void buildAndSendMsg(byte[] packet, COMMUNICATION_TYPE fwType, boolean t ObjectCluster objectCluster = null; try { objectCluster = buildMsg(packet, fwType, timeSync, pcTimeStamp); - if(objectCluster.successfullyParsed==false){ - printLogDataForDebugging("Packet timestamp is not contiguous - skipping:\t\t" + UtilShimmer.bytesToHexStringWithSpacesFormatted(packet)); - return; - } objectCluster = systemTimestampPlot.processSystemTimestampPlot(objectCluster); } catch (Exception e) { e.printStackTrace(); @@ -2818,7 +2814,6 @@ public void startStreaming() throws ShimmerException { initialiseStreaming(); - super.mLastReceivedTimeStampTicks = 0; mByteArrayOutputStream.reset(); mListofPCTimeStamps.clear(); writeInstruction(START_STREAMING_COMMAND); diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java index 66b2a8bad..63af95ac0 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java @@ -157,12 +157,6 @@ public enum OBJECTCLUSTER_TYPE{ public int mIndexUncal = 0; public boolean mEnableArraysDataStructure = false; - /** - * Indicates whether the packet was successfully parsed. Set to false when validation checks - * fail (e.g., timestamp contiguity check) to signal that the ObjectCluster should be discarded. - */ - public boolean successfullyParsed = true; - public class SensorDataPerType { public SensorDataPerType(int length) { diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java index c8352e27b..522f532e6 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java @@ -494,23 +494,6 @@ public class BTStream { public static final int MAX_NUMBER_OF_SIGNALS = 77;//50; //used to be 11 but now 13 because of the SR30 + 8 for 3d orientation public static final int MAX_INQUIRY_PACKET_SIZE = 47; - /** - * Maximum allowed gap between consecutive packet timestamps in ticks (10 seconds at 32768 Hz). - * Used to detect corrupted packets that pass CRC checks. - *

- * Why 10 seconds: Empirically chosen to balance between catching data corruption and allowing for - * occasional transmission delays. This value can be tuned based on expected packet arrival rates. - *

- * Setting to 0 disables this check entirely. - *

- * Relationship to timestamp rollover: This value must be less than half the timestamp rollover period - * (i.e., the maximum value before the timestamp counter wraps) to avoid false positives due to rollover. - *

- * Sampling rate: The value is calculated for a 32768 Hz sampling rate. If a different sampling rate is used, - * this value should be adjusted accordingly (ticks = seconds * sampling rate). - */ - public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); - public enum TEST_MODE { MAIN_TEST((byte)0, "Main Test"), LED_TEST((byte)1, "LED Test"), @@ -802,11 +785,6 @@ public String toString() { protected boolean mPastGSRFirstTime=true; // this is to fix a bug with SDLog v0.9 // ---------- GSR end ------------------ - - /** - * Stores the last received timestamp in ticks (for detecting corrupted packets). - */ - protected double mLastReceivedTimeStampTicks = 0; public ObjectCluster setLSLTimeIfAvailable(ObjectCluster ojc) { return ojc; @@ -945,24 +923,6 @@ public ObjectCluster buildMsg(byte[] newPacket, COMMUNICATION_TYPE fwType, boole if (getHardwareVersion()==HW_ID.SHIMMER_SR30 || getHardwareVersion()==HW_ID.SHIMMER_3 || getHardwareVersion()==HW_ID.SHIMMER_3R || getHardwareVersion()==HW_ID.SHIMMER_GQ_802154_LR || getHardwareVersion()==HW_ID.SHIMMER_GQ_802154_NR || getHardwareVersion()==HW_ID.SHIMMER_2R_GQ){ - - /* - * Even with checking for start and stop of packets while parsing and performing - * CRC checks, some corrupted packets can still slip through. This is a final - * check to help make sure the time stamp ticks are contiguous before parsing the - * packet. - */ - if (fwType == COMMUNICATION_TYPE.BLUETOOTH && CONTIGUOUS_TIMESTAMP_TICKS_LIMIT != 0) - { - double shimmerTimestampTicks = (double)newPacketInt[getSignalIndex(Configuration.Shimmer3.ObjectClusterSensorName.TIMESTAMP)]; - if(mLastReceivedTimeStampTicks!=0 - && Math.abs(shimmerTimestampTicks - mLastReceivedTimeStampTicks) > CONTIGUOUS_TIMESTAMP_TICKS_LIMIT) { - objectCluster.successfullyParsed = false; - return objectCluster; //discard packet - } - mLastReceivedTimeStampTicks = shimmerTimestampTicks; - } - parseTimestampShimmer3(fwType, objectCluster, uncalibratedData, uncalibratedDataUnits, calibratedData, calibratedDataUnits, sensorNames, newPacketInt); //OFFSET From d5b2c3d3e069e4fda4726ce8966e8d812ad195e1 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 3 Dec 2025 10:39:55 +0000 Subject: [PATCH 12/15] DEV-574 #time 10m restored some formatting and improved console print --- .../com/shimmerresearch/bluetooth/ShimmerBluetooth.java | 6 ++++-- .../main/java/com/shimmerresearch/driver/ObjectCluster.java | 2 +- .../main/java/com/shimmerresearch/driver/ShimmerObject.java | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index 207c93234..e4b71ae1b 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -1010,8 +1010,10 @@ else if(isSupportedInStreamCmds() && bufferTemp[getPacketSizeWithCrc()+2]==INSTR //TODO: ACK in bufferTemp[0] not handled //else if else { - printLogDataForDebugging("Packet syncing problem:\tExpected: " + (getPacketSizeWithCrc()+2) + "bytes. Buffer contains " + mByteArrayOutputStream.size() + "bytes" - + "\nBuffer = " + UtilShimmer.bytesToHexStringWithSpacesFormatted(mByteArrayOutputStream.toByteArray())); + printLogDataForDebugging("Unexpected packet header bytes. Expected size: " + getPacketSizeWithCrc() + + ", Packet 1 header: " + UtilShimmer.byteToHexStringFormatted(bufferTemp[0]) + + ", Packet 2 header: " + UtilShimmer.byteToHexStringFormatted(bufferTemp[getPacketSizeWithCrc() + 1]) + + "\nBuffer: " + UtilShimmer.bytesToHexStringWithSpacesFormatted(mByteArrayOutputStream.toByteArray())); discardBufferBytesToNextPacket(); // Skip to start of next packet } } diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java index 63af95ac0..29bf516b5 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ObjectCluster.java @@ -156,7 +156,7 @@ public enum OBJECTCLUSTER_TYPE{ public int mIndexCal = 0; public int mIndexUncal = 0; public boolean mEnableArraysDataStructure = false; - + public class SensorDataPerType { public SensorDataPerType(int length) { diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java index 522f532e6..cf852a799 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/driver/ShimmerObject.java @@ -785,7 +785,7 @@ public String toString() { protected boolean mPastGSRFirstTime=true; // this is to fix a bug with SDLog v0.9 // ---------- GSR end ------------------ - + public ObjectCluster setLSLTimeIfAvailable(ObjectCluster ojc) { return ojc; } @@ -923,6 +923,7 @@ public ObjectCluster buildMsg(byte[] newPacket, COMMUNICATION_TYPE fwType, boole if (getHardwareVersion()==HW_ID.SHIMMER_SR30 || getHardwareVersion()==HW_ID.SHIMMER_3 || getHardwareVersion()==HW_ID.SHIMMER_3R || getHardwareVersion()==HW_ID.SHIMMER_GQ_802154_LR || getHardwareVersion()==HW_ID.SHIMMER_GQ_802154_NR || getHardwareVersion()==HW_ID.SHIMMER_2R_GQ){ + parseTimestampShimmer3(fwType, objectCluster, uncalibratedData, uncalibratedDataUnits, calibratedData, calibratedDataUnits, sensorNames, newPacketInt); //OFFSET From 992069d16df6900090c7d88b7d5922df3d1d6661 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 3 Dec 2025 10:50:52 +0000 Subject: [PATCH 13/15] Update ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index e4b71ae1b..002869524 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -1310,7 +1310,7 @@ protected void discardBufferBytesToNextPacket(){ mByteArrayOutputStream.write(bTemp, offset, bTemp.length-offset); // discard first 'offset' bytes if(mEnablePCTimeStamps) { // Remove first `offset` elements from the original list (destructive, modifies same list) - mListofPCTimeStamps.subList(0, offset).clear(); + mListofPCTimeStamps.subList(0, Math.min(offset, mListofPCTimeStamps.size())).clear(); } consolePrintLn("Throw Bytes " + UtilShimmer.bytesToHexStringWithSpacesFormatted(Arrays.copyOfRange(bTemp, 0, offset))); } From 1214fef7f97f54b7a3f87d7cfcf63823553becb7 Mon Sep 17 00:00:00 2001 From: Mark Nolan Date: Wed, 3 Dec 2025 10:51:07 +0000 Subject: [PATCH 14/15] Update ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index 002869524..1ef3c0770 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java @@ -1318,7 +1318,7 @@ protected void discardBufferBytesToNextPacket(){ /** * Finds the offset/index of the next DATA_PACKET (0x00) or ACK_COMMAND_PROCESSED (0xFF) byte. * - * @param a byte array to search within + * @param buffer a byte array to search within * @return index of the first 0x00 or 0xFF byte found after position 0, or -1 if not found */ private static int findOffsetOfNextZeroOrFF(byte[] buffer) { From 8693d411e4f0e17d07457ca20a6ee369a189ed6f Mon Sep 17 00:00:00 2001 From: JongChern Date: Tue, 6 Jan 2026 13:33:20 +0800 Subject: [PATCH 15/15] added unit test --- .../comms/wiredProtocol/ShimmerCrc.java | 2 +- ...onShimmer3_Streaming_Contiguous_Check.java | 114 +++++++++++++++++ ...mmer3_Streaming_Contiguous_Check_Fail.java | 116 ++++++++++++++++++ ...3_Streaming_Contiguous_Check_Overflow.java | 114 +++++++++++++++++ ...icationShimmer3_Streaming_Throw_Bytes.java | 115 +++++++++++++++++ ...ationShimmer3_Streaming_Throw_Bytes_2.java | 115 +++++++++++++++++ .../ByteCommunicationSimulatorS3.java | 53 ++++++++ ..._streaming_timestamp_contiguous_check.java | 61 +++++++++ ...aming_timestamp_contiguous_check_fail.java | 61 +++++++++ ...g_timestamp_contiguous_check_overflow.java | 61 +++++++++ ...3_streaming_with_improved_throw_bytes.java | 64 ++++++++++ ...streaming_with_improved_throw_bytes_2.java | 64 ++++++++++ 12 files changed, 939 insertions(+), 1 deletion(-) create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Fail.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Overflow.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes_2.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_fail.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_overflow.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes.java create mode 100644 ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes_2.java diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/comms/wiredProtocol/ShimmerCrc.java b/ShimmerDriver/src/main/java/com/shimmerresearch/comms/wiredProtocol/ShimmerCrc.java index 1bd6d5348..8f541098c 100644 --- a/ShimmerDriver/src/main/java/com/shimmerresearch/comms/wiredProtocol/ShimmerCrc.java +++ b/ShimmerDriver/src/main/java/com/shimmerresearch/comms/wiredProtocol/ShimmerCrc.java @@ -9,7 +9,7 @@ public class ShimmerCrc { * @param b the byte to calculate the CRC on * @return the new CRC value */ - protected static int shimmerUartCrcByte(int crc, byte b) { + public static int shimmerUartCrcByte(int crc, byte b) { crc &= 0xFFFF; crc = ((crc & 0xFFFF) >>> 8) | ((crc & 0xFFFF) << 8); crc ^= (b&0xFF); diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check.java new file mode 100644 index 000000000..74bb8a4cb --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check.java @@ -0,0 +1,114 @@ +package com.shimmerresearch.shimmer3.communication; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.shimmerresearch.bluetooth.ShimmerBluetooth.BT_STATE; +import com.shimmerresearch.driver.BasicProcessWithCallBack; +import com.shimmerresearch.driver.CallbackObject; +import com.shimmerresearch.driver.ObjectCluster; +import com.shimmerresearch.driver.ShimmerMsg; +import com.shimmerresearch.driver.Configuration.COMMUNICATION_TYPE; +import com.shimmerresearch.driverUtilities.ChannelDetails; +import com.shimmerresearch.driverUtilities.SensorDetails; +import com.shimmerresearch.driverUtilities.ShimmerVerDetails.HW_ID; +import com.shimmerresearch.exceptions.ShimmerException; +import com.shimmerresearch.pcDriver.ShimmerPC; +import com.shimmerresearch.sensors.AbstractSensor; +import com.shimmerresearch.sensors.AbstractSensor.SENSORS; + +import bolts.TaskCompletionSource; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.concurrent.TimeUnit; +@FixMethodOrder(MethodSorters.NAME_ASCENDING) // Test methods will be run in alphabetical order +public class API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check extends BasicProcessWithCallBack{ + ShimmerPC mDevice; + TaskCompletionSource mCalibrationTask; + TaskCompletionSource mStreamingTask; + ByteCommunicationSimulatorS3 mByteCommunicationSimulatorS3; + + @Before + public void setUp() { + mByteCommunicationSimulatorS3 = new ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check("COM99"); + mDevice = new ShimmerPC("COM99"); + mDevice.setTestRadio(mByteCommunicationSimulatorS3); + setWaitForData(mDevice); + } + + ArrayList mListOJC; + @Test + public void test001_testStreaming() { + mListOJC = new ArrayList(); + mByteCommunicationSimulatorS3.setIsNewBMPSupported(false); + mCalibrationTask = new TaskCompletionSource(); + mDevice.connect("",""); + + mCalibrationTask = new TaskCompletionSource<>(); + mStreamingTask = new TaskCompletionSource(); + try { + boolean result = mCalibrationTask.getTask().waitForCompletion(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + mDevice.startStreaming(); + } catch (ShimmerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + mStreamingTask.getTask().waitForCompletion(2, TimeUnit.SECONDS); + if(mListOJC.size()!=2) {//only one is expected because only the first packet is followed which meets ShimmerBluetooth.processPacket requirements + assert(false); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + } + + + @Override + protected void processMsgFromCallback(ShimmerMsg shimmerMSG) { + // TODO Auto-generated method stub + int ind = shimmerMSG.mIdentifier; + + Object object = (Object) shimmerMSG.mB; + + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + CallbackObject callbackObject = (CallbackObject)object; + + if (callbackObject.mState == BT_STATE.CONNECTED) { + if (mDevice.isInitialised()) { + try { + Thread.sleep(200); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + } + } + } else if (ind == ShimmerPC.MSG_IDENTIFIER_DATA_PACKET) { + System.out.println("Shimmer MSG_IDENTIFIER_DATA_PACKET"); + ObjectCluster objc = (ObjectCluster) shimmerMSG.mB; + mListOJC.add(objc); + } + +} + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Fail.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Fail.java new file mode 100644 index 000000000..4bdc92711 --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Fail.java @@ -0,0 +1,116 @@ +package com.shimmerresearch.shimmer3.communication; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.shimmerresearch.bluetooth.ShimmerBluetooth.BT_STATE; +import com.shimmerresearch.driver.BasicProcessWithCallBack; +import com.shimmerresearch.driver.CallbackObject; +import com.shimmerresearch.driver.ObjectCluster; +import com.shimmerresearch.driver.ShimmerMsg; +import com.shimmerresearch.driver.ShimmerObject; +import com.shimmerresearch.driver.Configuration.COMMUNICATION_TYPE; +import com.shimmerresearch.driverUtilities.ChannelDetails; +import com.shimmerresearch.driverUtilities.SensorDetails; +import com.shimmerresearch.driverUtilities.ShimmerVerDetails.HW_ID; +import com.shimmerresearch.exceptions.ShimmerException; +import com.shimmerresearch.pcDriver.ShimmerPC; +import com.shimmerresearch.sensors.AbstractSensor; +import com.shimmerresearch.sensors.AbstractSensor.SENSORS; + +import bolts.TaskCompletionSource; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.concurrent.TimeUnit; +@FixMethodOrder(MethodSorters.NAME_ASCENDING) // Test methods will be run in alphabetical order +public class API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Fail extends BasicProcessWithCallBack{ + ShimmerPC mDevice; + TaskCompletionSource mCalibrationTask; + TaskCompletionSource mStreamingTask; + ByteCommunicationSimulatorS3 mByteCommunicationSimulatorS3; + public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); + @Before + public void setUp() { + mByteCommunicationSimulatorS3 = new ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_fail("COM99"); + mDevice = new ShimmerPC("COM99"); + mDevice.setTestRadio(mByteCommunicationSimulatorS3); + setWaitForData(mDevice); + } + + ArrayList mListOJC; + @Test + public void test001_testStreaming() { + mListOJC = new ArrayList(); + mByteCommunicationSimulatorS3.setIsNewBMPSupported(false); + mCalibrationTask = new TaskCompletionSource(); + mDevice.connect("",""); + + mCalibrationTask = new TaskCompletionSource<>(); + mStreamingTask = new TaskCompletionSource(); + try { + boolean result = mCalibrationTask.getTask().waitForCompletion(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + mDevice.startStreaming(); + System.out.println("Limit = " + CONTIGUOUS_TIMESTAMP_TICKS_LIMIT); + } catch (ShimmerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + mStreamingTask.getTask().waitForCompletion(2, TimeUnit.SECONDS); + if(mListOJC.size()!=2) {//only one is expected because only the first packet is followed which meets ShimmerBluetooth.processPacket requirements + assert(false); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + } + + + @Override + protected void processMsgFromCallback(ShimmerMsg shimmerMSG) { + // TODO Auto-generated method stub + int ind = shimmerMSG.mIdentifier; + + Object object = (Object) shimmerMSG.mB; + + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + CallbackObject callbackObject = (CallbackObject)object; + + if (callbackObject.mState == BT_STATE.CONNECTED) { + if (mDevice.isInitialised()) { + try { + Thread.sleep(200); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + } + } + } else if (ind == ShimmerPC.MSG_IDENTIFIER_DATA_PACKET) { + System.out.println("Shimmer MSG_IDENTIFIER_DATA_PACKET"); + ObjectCluster objc = (ObjectCluster) shimmerMSG.mB; + mListOJC.add(objc); + } + +} + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Overflow.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Overflow.java new file mode 100644 index 000000000..a4f46feec --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Overflow.java @@ -0,0 +1,114 @@ +package com.shimmerresearch.shimmer3.communication; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.shimmerresearch.bluetooth.ShimmerBluetooth.BT_STATE; +import com.shimmerresearch.driver.BasicProcessWithCallBack; +import com.shimmerresearch.driver.CallbackObject; +import com.shimmerresearch.driver.ObjectCluster; +import com.shimmerresearch.driver.ShimmerMsg; +import com.shimmerresearch.driver.Configuration.COMMUNICATION_TYPE; +import com.shimmerresearch.driverUtilities.ChannelDetails; +import com.shimmerresearch.driverUtilities.SensorDetails; +import com.shimmerresearch.driverUtilities.ShimmerVerDetails.HW_ID; +import com.shimmerresearch.exceptions.ShimmerException; +import com.shimmerresearch.pcDriver.ShimmerPC; +import com.shimmerresearch.sensors.AbstractSensor; +import com.shimmerresearch.sensors.AbstractSensor.SENSORS; + +import bolts.TaskCompletionSource; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.concurrent.TimeUnit; +@FixMethodOrder(MethodSorters.NAME_ASCENDING) // Test methods will be run in alphabetical order +public class API_0000X_ByteCommunicationShimmer3_Streaming_Contiguous_Check_Overflow extends BasicProcessWithCallBack{ + ShimmerPC mDevice; + TaskCompletionSource mCalibrationTask; + TaskCompletionSource mStreamingTask; + ByteCommunicationSimulatorS3 mByteCommunicationSimulatorS3; + + @Before + public void setUp() { + mByteCommunicationSimulatorS3 = new ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_overflow("COM99"); + mDevice = new ShimmerPC("COM99"); + mDevice.setTestRadio(mByteCommunicationSimulatorS3); + setWaitForData(mDevice); + } + + ArrayList mListOJC; + @Test + public void test001_testStreaming() { + mListOJC = new ArrayList(); + mByteCommunicationSimulatorS3.setIsNewBMPSupported(false); + mCalibrationTask = new TaskCompletionSource(); + mDevice.connect("",""); + + mCalibrationTask = new TaskCompletionSource<>(); + mStreamingTask = new TaskCompletionSource(); + try { + boolean result = mCalibrationTask.getTask().waitForCompletion(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + mDevice.startStreaming(); + } catch (ShimmerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + mStreamingTask.getTask().waitForCompletion(2, TimeUnit.SECONDS); + if(mListOJC.size()!=2) {//only one is expected because only the first packet is followed which meets ShimmerBluetooth.processPacket requirements + assert(false); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + } + + + @Override + protected void processMsgFromCallback(ShimmerMsg shimmerMSG) { + // TODO Auto-generated method stub + int ind = shimmerMSG.mIdentifier; + + Object object = (Object) shimmerMSG.mB; + + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + CallbackObject callbackObject = (CallbackObject)object; + + if (callbackObject.mState == BT_STATE.CONNECTED) { + if (mDevice.isInitialised()) { + try { + Thread.sleep(200); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + } + } + } else if (ind == ShimmerPC.MSG_IDENTIFIER_DATA_PACKET) { + System.out.println("Shimmer MSG_IDENTIFIER_DATA_PACKET"); + ObjectCluster objc = (ObjectCluster) shimmerMSG.mB; + mListOJC.add(objc); + } + +} + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes.java new file mode 100644 index 000000000..4b89df292 --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes.java @@ -0,0 +1,115 @@ +package com.shimmerresearch.shimmer3.communication; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.shimmerresearch.bluetooth.ShimmerBluetooth.BT_STATE; +import com.shimmerresearch.driver.BasicProcessWithCallBack; +import com.shimmerresearch.driver.CallbackObject; +import com.shimmerresearch.driver.ObjectCluster; +import com.shimmerresearch.driver.ShimmerMsg; +import com.shimmerresearch.driver.Configuration.COMMUNICATION_TYPE; +import com.shimmerresearch.driverUtilities.ChannelDetails; +import com.shimmerresearch.driverUtilities.SensorDetails; +import com.shimmerresearch.driverUtilities.ShimmerVerDetails.HW_ID; +import com.shimmerresearch.exceptions.ShimmerException; +import com.shimmerresearch.pcDriver.ShimmerPC; +import com.shimmerresearch.sensors.AbstractSensor; +import com.shimmerresearch.sensors.AbstractSensor.SENSORS; + +import bolts.TaskCompletionSource; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.concurrent.TimeUnit; +@FixMethodOrder(MethodSorters.NAME_ASCENDING) // Test methods will be run in alphabetical order +public class API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes extends BasicProcessWithCallBack{ + ShimmerPC mDevice; + TaskCompletionSource mCalibrationTask; + TaskCompletionSource mStreamingTask; + ByteCommunicationSimulatorS3 mByteCommunicationSimulatorS3; + + @Before + public void setUp() { + mByteCommunicationSimulatorS3 = new ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes("COM99"); + mDevice = new ShimmerPC("COM99"); + mDevice.setTestRadio(mByteCommunicationSimulatorS3); + setWaitForData(mDevice); + } + + ArrayList mListOJC; + @Test + public void test001_testStreaming() { + mListOJC = new ArrayList(); + mByteCommunicationSimulatorS3.setIsNewBMPSupported(false); + mCalibrationTask = new TaskCompletionSource(); + mDevice.connect("",""); + + mCalibrationTask = new TaskCompletionSource<>(); + mStreamingTask = new TaskCompletionSource(); + try { + boolean result = mCalibrationTask.getTask().waitForCompletion(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + mDevice.startStreaming(); + } catch (ShimmerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + mStreamingTask.getTask().waitForCompletion(2, TimeUnit.SECONDS); + System.out.println("Number of ObjectClusters received: " + mListOJC.size()); + if(mListOJC.size()!=1) {//only one is expected because only the first packet is followed by garbage bytes which causes the first packet to be thrown away + assert(false); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + } + + + @Override + protected void processMsgFromCallback(ShimmerMsg shimmerMSG) { + // TODO Auto-generated method stub + int ind = shimmerMSG.mIdentifier; + + Object object = (Object) shimmerMSG.mB; + + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + CallbackObject callbackObject = (CallbackObject)object; + + if (callbackObject.mState == BT_STATE.CONNECTED) { + if (mDevice.isInitialised()) { + try { + Thread.sleep(200); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + } + } + } else if (ind == ShimmerPC.MSG_IDENTIFIER_DATA_PACKET) { + System.out.println("Shimmer MSG_IDENTIFIER_DATA_PACKET"); + ObjectCluster objc = (ObjectCluster) shimmerMSG.mB; + mListOJC.add(objc); + } + +} + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes_2.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes_2.java new file mode 100644 index 000000000..a5ed4bd21 --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes_2.java @@ -0,0 +1,115 @@ +package com.shimmerresearch.shimmer3.communication; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.shimmerresearch.bluetooth.ShimmerBluetooth.BT_STATE; +import com.shimmerresearch.driver.BasicProcessWithCallBack; +import com.shimmerresearch.driver.CallbackObject; +import com.shimmerresearch.driver.ObjectCluster; +import com.shimmerresearch.driver.ShimmerMsg; +import com.shimmerresearch.driver.Configuration.COMMUNICATION_TYPE; +import com.shimmerresearch.driverUtilities.ChannelDetails; +import com.shimmerresearch.driverUtilities.SensorDetails; +import com.shimmerresearch.driverUtilities.ShimmerVerDetails.HW_ID; +import com.shimmerresearch.exceptions.ShimmerException; +import com.shimmerresearch.pcDriver.ShimmerPC; +import com.shimmerresearch.sensors.AbstractSensor; +import com.shimmerresearch.sensors.AbstractSensor.SENSORS; + +import bolts.TaskCompletionSource; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.concurrent.TimeUnit; +@FixMethodOrder(MethodSorters.NAME_ASCENDING) // Test methods will be run in alphabetical order +public class API_0000X_ByteCommunicationShimmer3_Streaming_Throw_Bytes_2 extends BasicProcessWithCallBack{ + ShimmerPC mDevice; + TaskCompletionSource mCalibrationTask; + TaskCompletionSource mStreamingTask; + ByteCommunicationSimulatorS3 mByteCommunicationSimulatorS3; + + @Before + public void setUp() { + mByteCommunicationSimulatorS3 = new ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes_2("COM99"); + mDevice = new ShimmerPC("COM99"); + mDevice.setTestRadio(mByteCommunicationSimulatorS3); + setWaitForData(mDevice); + } + + ArrayList mListOJC; + @Test + public void test001_testStreaming() { + mListOJC = new ArrayList(); + mByteCommunicationSimulatorS3.setIsNewBMPSupported(false); + mCalibrationTask = new TaskCompletionSource(); + mDevice.connect("",""); + + mCalibrationTask = new TaskCompletionSource<>(); + mStreamingTask = new TaskCompletionSource(); + try { + boolean result = mCalibrationTask.getTask().waitForCompletion(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + try { + mDevice.startStreaming(); + } catch (ShimmerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + try { + mStreamingTask.getTask().waitForCompletion(2, TimeUnit.SECONDS); + System.out.println("Number of ObjectClusters received: " + mListOJC.size()); + if(mListOJC.size()!=2) {//two is expected as the bytes thrown are before the first packet + assert(false); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + } + + + @Override + protected void processMsgFromCallback(ShimmerMsg shimmerMSG) { + // TODO Auto-generated method stub + int ind = shimmerMSG.mIdentifier; + + Object object = (Object) shimmerMSG.mB; + + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + if (ind == ShimmerPC.MSG_IDENTIFIER_STATE_CHANGE) { + CallbackObject callbackObject = (CallbackObject)object; + + if (callbackObject.mState == BT_STATE.CONNECTED) { + if (mDevice.isInitialised()) { + try { + Thread.sleep(200); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + } + } + } else if (ind == ShimmerPC.MSG_IDENTIFIER_DATA_PACKET) { + System.out.println("Shimmer MSG_IDENTIFIER_DATA_PACKET"); + ObjectCluster objc = (ObjectCluster) shimmerMSG.mB; + mListOJC.add(objc); + } + +} + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3.java index e6a9a54f0..4bb10e966 100644 --- a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3.java +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3.java @@ -3,6 +3,7 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; +import com.shimmerresearch.comms.wiredProtocol.ShimmerCrc; import com.shimmerresearch.driver.ShimmerObject; import com.shimmerresearch.driverUtilities.UtilShimmer; import com.shimmerresearch.verisense.communication.ByteCommunicationListener; @@ -294,5 +295,57 @@ public void removeRadioListenerList() { // TODO Auto-generated method stub } + + protected byte[] buildPacket(int timestamp) { + + byte ts0 = (byte)(timestamp & 0xFF); + byte ts1 = (byte)((timestamp >> 8) & 0xFF); + byte ts2 = (byte)((timestamp >> 16) & 0xFF); + + byte[] body = new byte[] { + 0x00, // DATA marker + ts0, ts1, ts2, // 24-bit timestamp + (byte)0xE7, + (byte)0x09, + (byte)0x3C, + (byte)0x08, + (byte)0x3F, + (byte)0x09 + }; + + // Full 16-bit CRC result (LSB/MSB) + byte[] crc = shimmerCrc16(body, body.length); + + // ONE-BYTE CRC packet → 10 bytes body + 1 byte CRC = 11 total + byte[] packet = new byte[body.length + 1]; + + System.arraycopy(body, 0, packet, 0, body.length); + + // Only append CRC LSB (crc[0]) + packet[10] = crc[0]; + + return packet; + } + + + + private byte[] shimmerCrc16(byte[] msg, int len) { + int CRC_INIT = 0xB0CA; + int crc = ShimmerCrc.shimmerUartCrcByte(CRC_INIT, msg[0]); + + for (int i = 1; i < len; i++) { + crc = ShimmerCrc.shimmerUartCrcByte(crc, msg[i]); + } + + if (len % 2 > 0) { + crc = ShimmerCrc.shimmerUartCrcByte(crc, (byte)0x00); + } + + byte[] out = new byte[2]; + out[0] = (byte)(crc & 0xFF); // LSB + out[1] = (byte)((crc >> 8) & 0xFF); // MSB + return out; + } + } diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check.java new file mode 100644 index 000000000..fbc9364d7 --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check.java @@ -0,0 +1,61 @@ +package com.shimmerresearch.shimmer3.communication; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import com.shimmerresearch.driver.ShimmerObject; +import com.shimmerresearch.driverUtilities.UtilShimmer; +import com.shimmerresearch.verisense.communication.ByteCommunicationListener; + +import jssc.SerialPortException; +import jssc.SerialPortTimeoutException; + +public class ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check extends ByteCommunicationSimulatorS3{ + public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); + public ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check(String address) { + super(address); + // TODO Auto-generated constructor stub + } + + @Override + protected void inquiryResponse() { + byte[] bytes = UtilShimmer.hexStringToByteArray("FF02800201FF010803010001020F"); + for (byte b:bytes) { + mBuffer.add(b); + } + } + @Override + protected void streaming() { + int numberOfPackets = 3; + + mBuffer.add((byte)0xFF); + mBuffer.add((byte)0xF4); + + + Thread streamingThread = new Thread(() -> { + try { + Thread.sleep(200); + int baseTimestamp = 0x000000; // EF BE 1B you used earlier + + for (int i = 0; i < numberOfPackets; i++) { + + byte[] packet = buildPacket(baseTimestamp); + baseTimestamp += (0.5 * CONTIGUOUS_TIMESTAMP_TICKS_LIMIT); + + + for (byte b : packet) { + mBuffer.add(b); + } + + Thread.sleep(100); + } + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }); + + streamingThread.start(); + } + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_fail.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_fail.java new file mode 100644 index 000000000..b5c859b43 --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_fail.java @@ -0,0 +1,61 @@ +package com.shimmerresearch.shimmer3.communication; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import com.shimmerresearch.driver.ShimmerObject; +import com.shimmerresearch.driverUtilities.UtilShimmer; +import com.shimmerresearch.verisense.communication.ByteCommunicationListener; + +import jssc.SerialPortException; +import jssc.SerialPortTimeoutException; + +public class ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_fail extends ByteCommunicationSimulatorS3{ + public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); + public ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_fail(String address) { + super(address); + // TODO Auto-generated constructor stub + } + + @Override + protected void inquiryResponse() { + byte[] bytes = UtilShimmer.hexStringToByteArray("FF02800201FF010803010001020F"); + for (byte b:bytes) { + mBuffer.add(b); + } + } + @Override + protected void streaming() { + int numberOfPackets = 3; + + mBuffer.add((byte)0xFF); + mBuffer.add((byte)0xF4); + + + Thread streamingThread = new Thread(() -> { + try { + Thread.sleep(200); + int baseTimestamp = 0x000001; // EF BE 1B you used earlier + + for (int i = 0; i < numberOfPackets; i++) { + + byte[] packet = buildPacket(baseTimestamp); + baseTimestamp += (2 * CONTIGUOUS_TIMESTAMP_TICKS_LIMIT); + + + for (byte b : packet) { + mBuffer.add(b); + } + + Thread.sleep(100); + } + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }); + + streamingThread.start(); + } + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_overflow.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_overflow.java new file mode 100644 index 000000000..f2124ea89 --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_overflow.java @@ -0,0 +1,61 @@ +package com.shimmerresearch.shimmer3.communication; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import com.shimmerresearch.driver.ShimmerObject; +import com.shimmerresearch.driverUtilities.UtilShimmer; +import com.shimmerresearch.verisense.communication.ByteCommunicationListener; + +import jssc.SerialPortException; +import jssc.SerialPortTimeoutException; + +public class ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_overflow extends ByteCommunicationSimulatorS3{ + + public ByteCommunicationSimulatorS3_streaming_timestamp_contiguous_check_overflow(String address) { + super(address); + // TODO Auto-generated constructor stub + } + + @Override + protected void inquiryResponse() { + byte[] bytes = UtilShimmer.hexStringToByteArray("FF02800201FF010803010001020F"); + for (byte b:bytes) { + mBuffer.add(b); + } + } + @Override + protected void streaming() { + int numberOfPackets = 3; + + mBuffer.add((byte)0xFF); + mBuffer.add((byte)0xF4); + + + Thread streamingThread = new Thread(() -> { + try { + Thread.sleep(200); + int baseTimestamp = 0xFFFFFE; // EF BE 1B you used earlier + + for (int i = 0; i < numberOfPackets; i++) { + + byte[] packet = buildPacket(baseTimestamp); + baseTimestamp += (1); + baseTimestamp &= 0xFFFFFF; // force 24-bit wrap + + for (byte b : packet) { + mBuffer.add(b); + } + + Thread.sleep(100); + } + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }); + + streamingThread.start(); + } + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes.java new file mode 100644 index 000000000..48641f527 --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes.java @@ -0,0 +1,64 @@ +package com.shimmerresearch.shimmer3.communication; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import com.shimmerresearch.driver.ShimmerObject; +import com.shimmerresearch.driverUtilities.UtilShimmer; +import com.shimmerresearch.verisense.communication.ByteCommunicationListener; + +import jssc.SerialPortException; +import jssc.SerialPortTimeoutException; + +public class ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes extends ByteCommunicationSimulatorS3{ + public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); + public ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes(String address) { + super(address); + // TODO Auto-generated constructor stub + } + + @Override + protected void inquiryResponse() { + byte[] bytes = UtilShimmer.hexStringToByteArray("FF02800201FF010803010001020F"); + for (byte b:bytes) { + mBuffer.add(b); + } + } + @Override + protected void streaming() { + int numberOfPackets = 3; + + mBuffer.add((byte)0xFF); + mBuffer.add((byte)0xF4); + boolean once = true; + + Thread streamingThread = new Thread(() -> { + try { + Thread.sleep(200); + int baseTimestamp = 0x010203; // EF BE 1B you used earlier + + for (int i = 0; i < numberOfPackets; i++) { + + byte[] packet = buildPacket(baseTimestamp); + //baseTimestamp += (0.5 * CONTIGUOUS_TIMESTAMP_TICKS_LIMIT); + + + for (byte b : packet) { + mBuffer.add(b); + } + if (i==0) { + mBuffer.add((byte) 0xEE); + mBuffer.add((byte) 0xEF); + } + Thread.sleep(100); + } + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }); + + streamingThread.start(); + } + +} diff --git a/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes_2.java b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes_2.java new file mode 100644 index 000000000..939a9dcde --- /dev/null +++ b/ShimmerDriverPC/src/test/java/com/shimmerresearch/shimmer3/communication/ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes_2.java @@ -0,0 +1,64 @@ +package com.shimmerresearch.shimmer3.communication; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import com.shimmerresearch.driver.ShimmerObject; +import com.shimmerresearch.driverUtilities.UtilShimmer; +import com.shimmerresearch.verisense.communication.ByteCommunicationListener; + +import jssc.SerialPortException; +import jssc.SerialPortTimeoutException; + +public class ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes_2 extends ByteCommunicationSimulatorS3{ + public static int CONTIGUOUS_TIMESTAMP_TICKS_LIMIT = (10*32768); + public ByteCommunicationSimulatorS3_streaming_with_improved_throw_bytes_2(String address) { + super(address); + // TODO Auto-generated constructor stub + } + + @Override + protected void inquiryResponse() { + byte[] bytes = UtilShimmer.hexStringToByteArray("FF02800201FF010803010001020F"); + for (byte b:bytes) { + mBuffer.add(b); + } + } + @Override + protected void streaming() { + int numberOfPackets = 3; + + mBuffer.add((byte)0xFF); + mBuffer.add((byte)0xF4); + boolean once = true; + + Thread streamingThread = new Thread(() -> { + try { + Thread.sleep(200); + int baseTimestamp = 0x010203; // EF BE 1B you used earlier + mBuffer.add((byte) 0xEE); + mBuffer.add((byte) 0xEF); + for (int i = 0; i < numberOfPackets; i++) { + + byte[] packet = buildPacket(baseTimestamp); + //baseTimestamp += (0.5 * CONTIGUOUS_TIMESTAMP_TICKS_LIMIT); + + + for (byte b : packet) { + mBuffer.add(b); + } + if (i==0) { + + } + Thread.sleep(100); + } + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }); + + streamingThread.start(); + } + +}