diff --git a/Client/Client.cs b/Client/Client.cs index 16d24ad..1a3392a 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -15,6 +15,8 @@ namespace Client private byte[] totalBuffer = new byte[1024]; private int totalBufferReceived = 0; private EngineConnection engineConnection; + private bool sessionRunning = false; + private IHandler handler = null; public Client() : this("localhost", 5555) @@ -48,7 +50,7 @@ namespace Client private void OnConnect(IAsyncResult ar) { this.client.EndConnect(ar); - Console.WriteLine("Verbonden!"); + Console.WriteLine("TCP client Verbonden!"); this.stream = this.client.GetStream(); @@ -100,6 +102,26 @@ namespace Client tryLogin(); } break; + case DataParser.START_SESSION: + this.sessionRunning = true; + sendMessage(DataParser.getStartSessionJson()); + break; + case DataParser.STOP_SESSION: + this.sessionRunning = false; + sendMessage(DataParser.getStopSessionJson()); + break; + case DataParser.SET_RESISTANCE: + if (this.handler == null) + { + Console.WriteLine("handler is null"); + sendMessage(DataParser.getSetResistanceResponseJson(false)); + } + else + { + this.handler.setResistance(DataParser.getResistanceFromJson(payloadbytes)); + sendMessage(DataParser.getSetResistanceResponseJson(true)); + } + break; default: Console.WriteLine($"Received json with identifier {identifier}:\n{Encoding.ASCII.GetString(payloadbytes)}"); break; @@ -118,6 +140,11 @@ namespace Client } + private void sendMessage(byte[] message) + { + stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null); + } + private void OnWrite(IAsyncResult ar) { this.stream.EndWrite(ar); @@ -127,6 +154,10 @@ namespace Client //maybe move this to other place public void BPM(byte[] bytes) { + if (!sessionRunning) + { + return; + } if (bytes == null) { throw new ArgumentNullException("no bytes"); @@ -137,6 +168,10 @@ namespace Client public void Bike(byte[] bytes) { + if (!sessionRunning) + { + return; + } if (bytes == null) { throw new ArgumentNullException("no bytes"); @@ -167,5 +202,10 @@ namespace Client this.stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null); } + + public void setHandler(IHandler handler) + { + this.handler = handler; + } } } diff --git a/Client/DataParser.cs b/Client/DataParser.cs index c83b86a..8eddb4c 100644 --- a/Client/DataParser.cs +++ b/Client/DataParser.cs @@ -3,6 +3,7 @@ using Newtonsoft.Json.Serialization; using System; using System.Globalization; using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; using System.Text; namespace Client @@ -10,7 +11,10 @@ namespace Client public class DataParser { public const string LOGIN = "LOGIN"; - public const string LOGIN_RESPONSE = "LOGIN_RESPONSE"; + public const string LOGIN_RESPONSE = "LOGIN RESPONSE"; + public const string START_SESSION = "START SESSION"; + public const string STOP_SESSION = "STOP SESSION"; + public const string SET_RESISTANCE = "SET RESISTANCE"; /// /// makes the json object with LOGIN identifier and username and password /// @@ -59,6 +63,15 @@ namespace Client return getMessage(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(json)), 0x01); } + private static byte[] getJsonMessage(string mIdentifier) + { + dynamic json = new + { + identifier = mIdentifier, + }; + return getMessage(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(json)), 0x01); + } + public static byte[] getLoginResponse(string mStatus) { return getJsonMessage(LOGIN_RESPONSE, new { status = mStatus }); @@ -150,15 +163,42 @@ namespace Client return getMessage(payload, 0x01); } - /// - /// constructs a message with the message and clientId - /// - /// - /// - /// the message ready for sending - public static byte[] getJsonMessage(string message) + public static byte[] getStartSessionJson() { - return getJsonMessage(Encoding.ASCII.GetBytes(message)); + return getJsonMessage(START_SESSION); + } + + public static byte[] getStopSessionJson() + { + return getJsonMessage(STOP_SESSION); + } + + public static byte[] getSetResistanceJson(float mResistance) + { + dynamic data = new + { + resistance = mResistance + }; + return getJsonMessage(SET_RESISTANCE, data); + } + + public static byte[] getSetResistanceResponseJson(bool mWorked) + { + dynamic data = new + { + worked = mWorked + }; + return getJsonMessage(SET_RESISTANCE, data); + } + + public static float getResistanceFromJson(byte[] json) + { + return ((dynamic)JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json))).data.resistance; + } + + public static bool getResistanceFromResponseJson(byte[] json) + { + return ((dynamic)JsonConvert.DeserializeObject(Encoding.ASCII.GetString(json))).data.worked; } diff --git a/Client/Program.cs b/Client/Program.cs index 9853e51..f8dd547 100644 --- a/Client/Program.cs +++ b/Client/Program.cs @@ -1,7 +1,6 @@ using System; using Hardware; using Hardware.Simulators; -using RH_Engine; namespace Client { @@ -20,13 +19,18 @@ namespace Client { } - //BLEHandler bLEHandler = new BLEHandler(client); + BLEHandler bLEHandler = new BLEHandler(client); - //bLEHandler.Connect(); + bLEHandler.Connect(); - BikeSimulator bikeSimulator = new BikeSimulator(client); + client.setHandler(bLEHandler); - bikeSimulator.StartSimulation(); + + //BikeSimulator bikeSimulator = new BikeSimulator(client); + + //bikeSimulator.StartSimulation(); + + //client.setHandler(bikeSimulator); while (true) { diff --git a/ProftaakRH/BLEHandler.cs b/ProftaakRH/BLEHandler.cs index 6baf843..269b0a1 100644 --- a/ProftaakRH/BLEHandler.cs +++ b/ProftaakRH/BLEHandler.cs @@ -11,7 +11,7 @@ namespace Hardware /// /// BLEHandler class that handles connection and traffic to and from the bike /// - public class BLEHandler + public class BLEHandler : IHandler { List dataReceivers; private BLE bleBike; @@ -25,11 +25,13 @@ namespace Hardware public BLEHandler(IDataReceiver dataReceiver) { this.dataReceivers = new List { dataReceiver }; + } public BLEHandler(List dataReceivers) { this.dataReceivers = dataReceivers; + } public void addDataReceiver(IDataReceiver dataReceiver) @@ -43,6 +45,7 @@ namespace Hardware public void Connect() { BLE bleBike = new BLE(); + Thread.Sleep(1000); // We need some time to list available devices // List available devices @@ -170,6 +173,11 @@ namespace Hardware /// The precentage of resistance to set public void setResistance(float percentage) { + if (!this.Running) + { + Console.WriteLine("BLE is not running"); + return; + } byte[] antMessage = new byte[13]; antMessage[0] = 0x4A; antMessage[1] = 0x09; diff --git a/ProftaakRH/BikeSimulator.cs b/ProftaakRH/BikeSimulator.cs index daea355..3d11209 100644 --- a/ProftaakRH/BikeSimulator.cs +++ b/ProftaakRH/BikeSimulator.cs @@ -98,32 +98,7 @@ namespace Hardware.Simulators return hartByte; } - //Generate an ANT message for resistance - public byte[] GenerateResistance(float percentage) - { - byte[] antMessage = new byte[13]; - antMessage[0] = 0x4A; - antMessage[1] = 0x09; - antMessage[2] = 0x4E; - antMessage[3] = 0x05; - antMessage[4] = 0x30; - for (int i = 5; i < 11; i++) - { - antMessage[i] = 0xFF; - } - antMessage[11] = (byte)Math.Max(Math.Min(Math.Round(percentage / 0.5), 255), 0); - //antMessage[11] = 50; //hardcoded for testing - byte checksum = 0; - for (int i = 0; i < 12; i++) - { - checksum ^= antMessage[i]; - } - - antMessage[12] = checksum;//reminder that i am dumb :P - - return antMessage; - } //Calculates the needed variables //Input perlin value @@ -143,20 +118,11 @@ namespace Hardware.Simulators } //Set resistance in simulated bike - public void setResistance(byte[] bytes) + public void setResistance(float percentage) { - //TODO check if message is correct - if (bytes.Length == 13) - { - this.resistance = Convert.ToDouble(bytes[11]) / 2; - } + this.resistance = (byte)Math.Max(Math.Min(Math.Round(percentage / 0.5), 255), 0); } - } - - //Interface for receiving a message on the simulated bike - interface IHandler - { - void setResistance(byte[] bytes); } + } diff --git a/ProftaakRH/IHandler.cs b/ProftaakRH/IHandler.cs new file mode 100644 index 0000000..4f52042 --- /dev/null +++ b/ProftaakRH/IHandler.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ProftaakRH +{ + public interface IHandler + { + void setResistance(float percentage); + } +} diff --git a/ProftaakRH/Main.cs b/ProftaakRH/Main.cs index 5ffcab4..41780f0 100644 --- a/ProftaakRH/Main.cs +++ b/ProftaakRH/Main.cs @@ -14,7 +14,7 @@ namespace ProftaakRH IDataReceiver dataReceiver = new DataConverter(); BLEHandler bLEHandler = new BLEHandler(dataReceiver); BikeSimulator bikeSimulator = new BikeSimulator(dataReceiver); - bikeSimulator.setResistance(bikeSimulator.GenerateResistance(1f)); + bikeSimulator.setResistance(1); bikeSimulator.StartSimulation(); diff --git a/Server/Client.cs b/Server/Client.cs index 5e385be..02abad4 100644 --- a/Server/Client.cs +++ b/Server/Client.cs @@ -103,40 +103,61 @@ namespace Server { Console.WriteLine("Log in"); this.username = username; - byte[] response = DataParser.getLoginResponse("OK"); - stream.BeginWrite(response, 0, response.Length, new AsyncCallback(OnWrite), null); - this.saveData = new SaveData(Directory.GetCurrentDirectory() + "/" + username, sessionStart.ToString("yyyy-MM-dd HH-mm-ss")); + sendMessage(DataParser.getLoginResponse("OK")); + sendMessage(DataParser.getStartSessionJson()); } else { - byte[] response = DataParser.getLoginResponse("wrong username or password"); - stream.BeginWrite(response, 0, response.Length, new AsyncCallback(OnWrite), null); + sendMessage(DataParser.getLoginResponse("wrong username or password")); } } else { - byte[] response = DataParser.getLoginResponse("invalid json"); - stream.BeginWrite(response, 0, response.Length, new AsyncCallback(OnWrite), null); + sendMessage(DataParser.getLoginResponse("invalid json")); } break; + case DataParser.START_SESSION: + this.saveData = new SaveData(Directory.GetCurrentDirectory() + "/" + this.username + "/" + sessionStart.ToString("yyyy-MM-dd HH-mm-ss")); + break; + case DataParser.STOP_SESSION: + this.saveData = null; + break; + case DataParser.SET_RESISTANCE: + worked = DataParser.getResistanceFromResponseJson(payloadbytes); + Console.WriteLine($"set resistance worked is " + worked); + //set resistance on doctor GUI + break; default: Console.WriteLine($"Received json with identifier {identifier}:\n{Encoding.ASCII.GetString(payloadbytes)}"); break; } - Array.Copy(message, 5, payloadbytes, 0, message.Length - 5); - dynamic json = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(payloadbytes)); - saveData.WriteDataJSON(Encoding.ASCII.GetString(payloadbytes)); - + saveData?.WriteDataJSON(Encoding.ASCII.GetString(payloadbytes)); } else if (DataParser.isRawData(message)) { - Console.WriteLine(BitConverter.ToString(message)); - saveData.WriteDataRAW(ByteArrayToString(message)); + Console.WriteLine(BitConverter.ToString(payloadbytes)); + if (payloadbytes.Length == 8) + { + saveData?.WriteDataRAWBike(payloadbytes); + } + else if (payloadbytes.Length == 2) + { + saveData?.WriteDataRAWBPM(payloadbytes); + } + else + { + Console.WriteLine("received raw data with weird lenght " + BitConverter.ToString(payloadbytes)); + } } } + private void sendMessage(byte[] message) + { + stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null); + } + private bool verifyLogin(string username, string password) { return username == password; diff --git a/Server/SaveData.cs b/Server/SaveData.cs index 0286bde..15fd0d4 100644 --- a/Server/SaveData.cs +++ b/Server/SaveData.cs @@ -8,11 +8,9 @@ namespace Server class SaveData { private string path; - private string filename; - public SaveData(string path, string filename) + public SaveData(string path) { this.path = path; - this.filename = filename; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); @@ -22,21 +20,53 @@ namespace Server /// /// Every line is a new data entry /// - + public void WriteDataJSON(string data) { - using (StreamWriter sw = File.AppendText(this.path + "/json"+filename+".txt")) + using (StreamWriter sw = File.AppendText(this.path + "/json" + ".txt")) { sw.WriteLine(data); } } - public void WriteDataRAW(string data) + public void WriteDataRAWBPM(byte[] data) { - using (StreamWriter sw = File.AppendText(this.path + "/raw" + filename + ".txt")) + if (data.Length != 2) { - sw.WriteLine(data); + throw new ArgumentException("data should have length of 2"); + } + WriteRawData(data, this.path + "/rawBPM" + ".bin"); + } + + public void WriteDataRAWBike(byte[] data) + { + if (data.Length != 8) + { + throw new ArgumentException("data should have length of 8"); + } + WriteRawData(data, this.path + "/rawBike" + ".bin"); + } + + private void WriteRawData(byte[] data, string fileLocation) + { + int length = 0; + try + { + FileInfo fi = new FileInfo(fileLocation); + length = (int)fi.Length; + } + catch + { + // do nothing + } + using (BinaryWriter sw = new BinaryWriter(File.Open(fileLocation, FileMode.Create))) + { + sw.Seek(length, SeekOrigin.End); + sw.Write(data); + sw.Flush(); } } + + } }