From 50a39f0d471bdf10300e8f90fb81849e68edb399 Mon Sep 17 00:00:00 2001 From: weiwentan23 Date: Wed, 26 Jan 2022 15:01:19 +0800 Subject: [PATCH 1/3] Add prod config unit test --- .../Communications/VerisenseProdConfigTest.cs | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 ShimmerBLE/ShimmerBLETests/Communications/VerisenseProdConfigTest.cs diff --git a/ShimmerBLE/ShimmerBLETests/Communications/VerisenseProdConfigTest.cs b/ShimmerBLE/ShimmerBLETests/Communications/VerisenseProdConfigTest.cs new file mode 100644 index 00000000..2f02f8f8 --- /dev/null +++ b/ShimmerBLE/ShimmerBLETests/Communications/VerisenseProdConfigTest.cs @@ -0,0 +1,205 @@ +using FakeItEasy; +using NUnit.Framework; +using shimmer.Models; +using ShimmerBLEAPI.Devices; +using ShimmerBLETests.Communications; +using System.Threading.Tasks; +using Xamarin.Forms; +using Xamarin.Forms.Internals; +using System; +using static shimmer.Models.ShimmerBLEEventData; +using static shimmer.Models.ProdConfigPayload; +using System.Diagnostics; +using System.IO; +using shimmer.Sensors; +using ShimmerAPI; +namespace ShimmerBLETests +{ + class VerisenseProdConfigTest + { + readonly byte[] defaultProdConfigBytes = new byte[] { 0x33, 0x37, 0x00, 0x5A, 0xBB, 0xA2, 0x01, 0x25, 0x09, 0x19, 0x01, 0x00, 0x01, 0x02, 0x63, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + readonly int PasskeyIDLength = 2; + readonly int PasskeyLength = 6; + readonly int AdvertisingNameLength = 32; + + [Test] + public void TestEnableClinicalTrialPasskey() + { + ProdConfigPayload prodConfig = new ProdConfigPayload(); + prodConfig.ProcessPayload(defaultProdConfigBytes); + prodConfig.EnableNoPasskey("TEST"); + prodConfig.EnableClinicalTrialPasskey(); + + byte[] prodConfigByteArray = prodConfig.GetPayload(); + + for (int i = 0; i < PasskeyIDLength; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY_ID + i] != 0xFF) + { + Assert.Fail(); + } + } + for (int i = 0; i < PasskeyLength; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY + i] != 0xFF) + { + Assert.Fail(); + } + } + for (int i = 0; i < AdvertisingNameLength; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + i] != 0xFF) + { + Assert.Fail(); + } + } + } + + [Test] + public void TestEnableNoPasskey() + { + ProdConfigPayload prodConfig = new ProdConfigPayload(); + prodConfig.ProcessPayload(defaultProdConfigBytes); + string advertisingName = "aaaaaaaa"; + prodConfig.EnableNoPasskey(advertisingName); + + byte[] prodConfigByteArray = prodConfig.GetPayload(); + + //passkey id 00 + for (int i = 0; i < PasskeyIDLength; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY_ID + i] != 0x30) + { + Assert.Fail(); + } + } + for (int i = 0; i < PasskeyLength; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY + i] != 0xFF) + { + Assert.Fail(); + } + } + for (int i = 0; i < advertisingName.Length; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + i] != 0x61) + { + Assert.Fail(); + } + } + for (int i = advertisingName.Length; i < AdvertisingNameLength; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + i] != 0xFF) + { + Assert.Fail(); + } + } + } + + [Test] + public void TestEnableDefaultPasskey() + { + ProdConfigPayload prodConfig = new ProdConfigPayload(); + prodConfig.ProcessPayload(defaultProdConfigBytes); + string advertisingName = "aaaaaaaa"; + string passkeyId = "01"; + prodConfig.EnableDefaultPasskey(advertisingName, passkeyId); + byte[] prodConfigByteArray = prodConfig.GetPayload(); + + //passkey id 01 + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY_ID] != 0x30 || + prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY_ID + 1] != 0x31) + { + Assert.Fail(); + } + // passkey 123456 + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY] != 0x31 || + prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY + 1] != 0x32 || + prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY + 2] != 0x33 || + prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY + 3] != 0x34 || + prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY + 4] != 0x35 || + prodConfigByteArray[(int)ConfigurationBytesIndexName.PASSKEY + 5] != 0x36) + { + Assert.Fail(); + } + for (int i = 0; i < advertisingName.Length; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + i] != 0x61) + { + Assert.Fail(); + } + } + for (int i = advertisingName.Length; i < AdvertisingNameLength; i++) + { + if (prodConfigByteArray[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + i] != 0xFF) + { + Assert.Fail(); + } + } + } + + [Test] + public void TestProcessPayload() + { + var prodConfigBytes = new byte[defaultProdConfigBytes.Length]; + Array.Copy(defaultProdConfigBytes, prodConfigBytes, defaultProdConfigBytes.Length); + + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY_ID + 3] = 0x30; + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY_ID + 4] = 0x31; + + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY + 3] = 0x31; + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY + 4] = 0x31; + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY + 5] = 0x31; + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY + 6] = 0x31; + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY + 7] = 0x31; + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY + 8] = 0x31; + + prodConfigBytes[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + 3] = 0x54; + prodConfigBytes[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + 4] = 0x45; + prodConfigBytes[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + 5] = 0x53; + prodConfigBytes[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + 6] = 0x54; + + ProdConfigPayload prodConfig = new ProdConfigPayload(); + prodConfig.ProcessPayload(prodConfigBytes); + + if(prodConfig.AdvertisingNamePrefix != "TEST") + { + Assert.Fail(); + } + if (prodConfig.PasskeyID != "01") + { + Assert.Fail(); + } + if (prodConfig.Passkey != "111111") + { + Assert.Fail(); + } + + for (int i = 0; i < PasskeyIDLength; i++) + { + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY_ID + 3 + i] = 0xFF; + } + for (int i = 0; i < PasskeyLength; i++) + { + prodConfigBytes[(int)ConfigurationBytesIndexName.PASSKEY + 3 + i] = 0xFF; + } + for (int i = 0; i < AdvertisingNameLength; i++) + { + prodConfigBytes[(int)ConfigurationBytesIndexName.ADVERTISING_NAME_PREFIX + 3 + i] = 0xFF; + } + prodConfig.ProcessPayload(prodConfigBytes); + if (prodConfig.AdvertisingNamePrefix != "Verisense") + { + Assert.Fail(); + } + if (prodConfig.PasskeyID != "") + { + Assert.Fail(); + } + if (prodConfig.Passkey != "") + { + Assert.Fail(); + } + } + } +} From 1d47f214cfc1fd821b9504ace5ca0d27b0236096 Mon Sep 17 00:00:00 2001 From: weiwentan23 Date: Wed, 26 Jan 2022 15:08:48 +0800 Subject: [PATCH 2/3] Add unit test for streaming GSR Verisense Pulse Plus --- .../Communications/TestByteRadio.cs | 9 +++ .../Communications/VerisenseStreamingTest.cs | 74 +++++++++++++++++++ .../Devices/TestVerisenseBLEDevice.cs | 16 ++++ 3 files changed, 99 insertions(+) diff --git a/ShimmerBLE/ShimmerBLETests/Communications/TestByteRadio.cs b/ShimmerBLE/ShimmerBLETests/Communications/TestByteRadio.cs index 4ce91c8d..f228cc48 100644 --- a/ShimmerBLE/ShimmerBLETests/Communications/TestByteRadio.cs +++ b/ShimmerBLE/ShimmerBLETests/Communications/TestByteRadio.cs @@ -229,6 +229,15 @@ public void InjectRawPacketGSR() } } + public void InjectRawPacketGSRVerisensePulsePlus() + { + byte[] rawPacket = new byte[] { 58, 198, 0, 1, 226, 36, 28, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 5, 11, 144, 196, 227, 224 }; + if (CommunicationEvent != null) + { + CommunicationEvent.Invoke(null, new ByteLevelCommunicationEvent { Bytes = rawPacket, Event = ByteLevelCommunicationEvent.CommEvent.NewBytes }); + } + } + public void InjectRawPacketPPG() { byte[] rawPacket = new byte[] { 58, 210, 0, 4, 115, 160, 26, diff --git a/ShimmerBLE/ShimmerBLETests/Communications/VerisenseStreamingTest.cs b/ShimmerBLE/ShimmerBLETests/Communications/VerisenseStreamingTest.cs index 003b09d8..7b0c6cec 100644 --- a/ShimmerBLE/ShimmerBLETests/Communications/VerisenseStreamingTest.cs +++ b/ShimmerBLE/ShimmerBLETests/Communications/VerisenseStreamingTest.cs @@ -271,6 +271,80 @@ public async Task StreamDataGSR() } } + [Test] + public async Task StreamDataGSRUsingVerisensePulsePlus() + { + //Byte and bit index starts with 0 + //Disable all sensors (Byte 1 = 0b00010111 = 0x17) + //Enable GSR (Byte 2 = 0b10000000 = 0x80) + //Enable Batt (Byte 3 = 0b00000010 = 0x02) + byte[] defaultBytes = new byte[] { 0x5A, 0x17, 0x80, 0x02, 0x00, 0x30, 0x20, 0x00, 0x7F, 0x00, 0xD8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF4, 0x18, 0x3C, 0x00, 0x0A, 0x0F, 0x00, 0x18, 0x3C, 0x00, 0x0A, 0x0F, 0x00, 0x18, 0x3C, 0x00, 0x0A, 0x0F, 0x00, 0xFF, + //GSR AUTO RANGE BYTE 51 = 0x04 + 0x04, 0xAA, 0x01, 0x03, 0x3C, 0x00, 0x0E, 0x00, 0x00, 0x63, 0x28, 0xCC, 0xCC, 0x1E, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x01 }; + byte[] prodConfigBytes = new byte[] { 51, 13, 0, 90, 230, 132, 1, 39, 8, 33, 68, 7, 1, 2, 98, 0 }; + + Boolean packetCorrectValue = true; + Boolean packetReceived = false; + TestVerisenseBLEDevice VerisenseBLEDevice = new TestVerisenseBLEDevice(uuid, "", defaultBytes, prodConfigBytes); + VerisenseBLEDevice.ShimmerBLEEvent += delegate (object sender, ShimmerBLEEventData e) + { + if (e.CurrentEvent == VerisenseBLEEvent.StateChange) + { + Trace.WriteLine("Shimmer State: " + VerisenseBLEDevice.GetVerisenseBLEState().ToString()); + }; + + if (e.CurrentEvent == VerisenseBLEEvent.NewDataPacket) + { + ObjectCluster ojc = ((ObjectCluster)e.ObjMsg); + var gsrOhms = ojc.GetData(SensorGSR.ObjectClusterSensorName.GSR, ShimmerConfiguration.SignalFormats.CAL, "kOhms").Data; + var gsrSiemens = ojc.GetData(SensorGSR.ObjectClusterSensorName.GSR, ShimmerConfiguration.SignalFormats.CAL, "uSiemens").Data; + var batt = ojc.GetData(SensorGSR.ObjectClusterSensorName.Batt, ShimmerConfiguration.SignalFormats.CAL).Data; + packetReceived = true; + double gsrOhmsExpectedValue = 58593.08594329789; + double gsrSiemensExpectedValue = 0.017066860089392236; + double battExpectedValue = 1240; + if (Math.Abs(gsrOhms - gsrOhmsExpectedValue) < 1 + && Math.Abs(gsrSiemens - gsrSiemensExpectedValue) < .3 + && Math.Abs(batt - battExpectedValue) < 1) + { + packetCorrectValue = true; + } + else + { + packetCorrectValue = false; + } + + }; + }; + + var result = await VerisenseBLEDevice.Connect(false); + if (result && VerisenseBLEDevice.GetVerisenseBLEState() == shimmer.Communications.ShimmerDeviceBluetoothState.Connected) + { + await VerisenseBLEDevice.ExecuteRequest(RequestType.StartStreaming); + + if (VerisenseBLEDevice.GetVerisenseBLEState() == shimmer.Communications.ShimmerDeviceBluetoothState.Streaming) + { + try + { + ((TestVerisenseBLEDevice)VerisenseBLEDevice).InjectRawPacketGSRVerisensePulsePlus(); + } + catch (Exception ex) + { + Assert.Fail(); + } + } + } + + if (packetCorrectValue && packetReceived) + { + Assert.Pass(); + } + else + { + Assert.Fail(); + } + } + [Test] public async Task StreamDataPPG() { diff --git a/ShimmerBLE/ShimmerBLETests/Devices/TestVerisenseBLEDevice.cs b/ShimmerBLE/ShimmerBLETests/Devices/TestVerisenseBLEDevice.cs index fc601ef3..084d7c0a 100644 --- a/ShimmerBLE/ShimmerBLETests/Devices/TestVerisenseBLEDevice.cs +++ b/ShimmerBLE/ShimmerBLETests/Devices/TestVerisenseBLEDevice.cs @@ -25,6 +25,17 @@ public TestVerisenseBLEDevice(string id, string name, byte[] opconfigbytes) : ba Array.Copy(opconfigbytes, OpConfig.ConfigurationBytes, opconfigbytes.Length); //deep copy UpdateDeviceAndSensorConfiguration(); } + + public TestVerisenseBLEDevice(string id, string name, byte[] opconfigbytes, byte[] prodconfigbytes) : base(id, name) + { + OpConfig = new OpConfigPayload(); + OpConfig.ConfigurationBytes = new byte[opconfigbytes.Length]; + ProdConfig = new ProdConfigPayload(); + ProdConfig.ProcessPayload(prodconfigbytes); + Array.Copy(opconfigbytes, OpConfig.ConfigurationBytes, opconfigbytes.Length); //deep copy + UpdateDeviceAndSensorConfiguration(); + } + protected override void InitializeRadio() { BLERadio = new TestByteRadio(); @@ -85,6 +96,11 @@ public void InjectRawPacketGSR() ((TestByteRadio)BLERadio).InjectRawPacketGSR(); } + public void InjectRawPacketGSRVerisensePulsePlus() + { + ((TestByteRadio)BLERadio).InjectRawPacketGSRVerisensePulsePlus(); + } + public void InjectRawPacketPPG() { ((TestByteRadio)BLERadio).InjectRawPacketPPG(); From 82ff50d3f42756874b5e4c83950f06692ae7e2bc Mon Sep 17 00:00:00 2001 From: weiwentan23 Date: Wed, 26 Jan 2022 15:29:51 +0800 Subject: [PATCH 3/3] minor fixed --- ShimmerBLE/ShimmerBLEAPI/Models/ProdConfigPayload.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShimmerBLE/ShimmerBLEAPI/Models/ProdConfigPayload.cs b/ShimmerBLE/ShimmerBLEAPI/Models/ProdConfigPayload.cs index 7a7577b3..723f9a74 100644 --- a/ShimmerBLE/ShimmerBLEAPI/Models/ProdConfigPayload.cs +++ b/ShimmerBLE/ShimmerBLEAPI/Models/ProdConfigPayload.cs @@ -38,7 +38,7 @@ public enum ConfigurationBytesIndexName public ProdConfigPayload(string payload) { Payload = payload; - ProcessPayload(GetPayload()); + ProcessPayload(GetPayloadWithHeader()); } public ProdConfigPayload()