diff --git a/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java b/ShimmerDriver/src/main/java/com/shimmerresearch/bluetooth/ShimmerBluetooth.java index ec441ad7f..1ef3c0770 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,17 +1002,19 @@ 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 } } //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())); - discardFirstBufferByte(); //throw the first byte away + 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 } } @@ -1052,7 +1054,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; } } @@ -1294,16 +1296,38 @@ 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); // discard first 'offset' bytes if(mEnablePCTimeStamps) { - mListofPCTimeStamps.remove(0); + // Remove first `offset` elements from the original list (destructive, modifies same list) + mListofPCTimeStamps.subList(0, Math.min(offset, mListofPCTimeStamps.size())).clear(); + } + 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 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) { + for (int i = 1; i < buffer.length; i++) { + byte b = buffer[i]; + if (b == 0 || b == (byte) 0xFF) + return i; } - consolePrintLn("Throw Byte" + UtilShimmer.bytesToHexStringWithSpacesFormatted(bTemp)); + return -1; } /** 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(); + } + +}