public void GetLastLogQueryResult(ISerial serial, int timeout) { List <byte> list = new List <byte>(5); list.Add(37); list.Add(254); list.Add(21); list.Add(0); list.Add(GetChecksum(list)); byte[] stream = list.ToArray(); serial.Write(stream, 0, stream.Length); byte[] rawBuffer = new byte[10]; int response_offest = 0; if (serial.isEcho()) { response_offest = stream.Length; } Array.Resize(ref rawBuffer, (int)(response_offest + 5)); long timeout_limit = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (timeout); while (serial.BytesToRead() < rawBuffer.Length) { if (DateTimeOffset.Now.ToUnixTimeMilliseconds() > timeout_limit) { //if even no data response no puck error.. if (serial.BytesToRead() <= response_offest) { throw new IOException(); } else { throw new TimeoutException(); } } Thread.Sleep(10); } serial.Read(rawBuffer, 0, rawBuffer.Length); byte[] response = new byte[5]; Array.Copy(rawBuffer, response.Length, response, 0, response.Length); if (response[0] != 0x06) { throw new LexiWriteException(response); } }
public void TriggerReadEventLogs(ISerial serial, DateTime start, DateTime end, int timeout) { List <byte> list = new List <byte>(17); list.Add(37); list.Add(254); list.Add(19); list.Add(10); list.Add(GetChecksum(list)); list.Add(1); list.Add(1); if (start.CompareTo(new DateTime(1970, 1, 1, 0, 0, 0)) < 0) { start = new DateTime(1970, 1, 1, 0, 0, 0); } byte[] timeSinceEventEpoch = GetTimeSinceEventEpoch(start); list.AddRange(timeSinceEventEpoch.Take(4)); byte[] timeSinceEventEpoch2 = GetTimeSinceEventEpoch(end); list.AddRange(timeSinceEventEpoch2.Take(4)); list.AddRange(CalcCrcNew(list.Skip(5).Take(10).ToArray())); byte[] stream = list.ToArray(); serial.Write(stream, 0, stream.Length); byte[] rawBuffer = new byte[2]; int response_offest = 0; if (serial.isEcho()) { response_offest = stream.Length; } Array.Resize(ref rawBuffer, (int)(response_offest + 2)); long timeout_limit = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (timeout); while (serial.BytesToRead() < rawBuffer.Length - 1) { if (DateTimeOffset.Now.ToUnixTimeMilliseconds() > timeout_limit) { //if even no data response no puck error.. if (serial.BytesToRead() <= response_offest) { throw new IOException(); } else { throw new TimeoutException(); } } Thread.Sleep(10); } serial.Read(rawBuffer, 0, (int)(rawBuffer.Length)); byte[] response = new byte[2]; Array.Copy(rawBuffer, response_offest, response, 0, response.Length); if (response[0] != 0x06) { throw new LexiWriteException(response); } }
public void Write(ISerial serial, UInt32 addres, byte[] data, int timeout) { /* * +------------+----------+----------------------------------------------------------+ * | Byte Index | Field | Notes | * +------------+----------+----------------------------------------------------------+ * | 0 | Header | This field is always 0x25 | * | 1 | Command | 0x81, 0x83, 0x85, 0x87 as detailed in section 4.2 above | * | 2 | Address | Address of first byte to write | * | 3 | Size | Number of bytes to write | * | 4 | Checksum | 2’s complement of sum: header + command + address + data | * | 5..4+N | Data | N = number of bytes specified in Data/Size field above | * | 6+N..7+N | CRC | See section 7.2 | * +------------+----------+----------------------------------------------------------+ * * Command * ------- * block 0 addres >= 0 & < 256 = 0x81 => 129 * block 1: addres >= 256 & < 512 = 0x83 => 131 * block 2:addres >= 512 & < 768 = 0x85 => 133 * block 3:addres >= 768 = 0x87 => 135 */ uint write_comand = (uint)(129 + ((addres / 256) * 2)); /* Address * ------- * addres then become offset from 256 block * Example: Addres 600 --> block 2 --> offset 600 - 512 = 88; */ uint start_addres = (uint)(addres - ((addres / 256) * 256)); byte[] payload = new byte[] { 0x25, // header (byte)write_comand, (byte)start_addres, (byte)data.Length }; //Addes checksum to payload byte[] header = checkSum(payload); byte[] stream = new byte[0]; Array.Resize(ref stream, (int)(header.Length + data.Length)); Array.Copy(header, 0, stream, 0, header.Length); Array.Copy(data, 0, stream, header.Length, data.Length); byte[] crc_bytes = BitConverter.GetBytes(calcCRC(data, data.Length)); Array.Resize(ref stream, (int)(header.Length + data.Length + 2)); stream[stream.Length - 1] = crc_bytes[1]; stream[stream.Length - 2] = crc_bytes[0]; serial.Write(stream, 0, stream.Length); byte[] rawBuffer = new byte[2]; int response_offest = 0; if (serial.isEcho()) { response_offest = stream.Length; } Array.Resize(ref rawBuffer, (int)(response_offest + 2)); long timeout_limit = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (timeout); while (serial.BytesToRead() < rawBuffer.Length - 1) { if (DateTimeOffset.Now.ToUnixTimeMilliseconds() > timeout_limit) { if (serial.BytesToRead() <= response_offest) { throw new IOException(); } else { throw new TimeoutException(); } } Thread.Sleep(10); } serial.Read(rawBuffer, 0, (int)(rawBuffer.Length)); byte[] response = new byte[2]; Array.Copy(rawBuffer, response_offest, response, 0, response.Length); if (response[0] != 0x06) { throw new LexiWriteException(response); } }
private bool checkResponseOk(ISerial serial, byte[] rawBuffer) { return(serial.BytesToRead() < rawBuffer.Length); }
/// <summary> /// Request to read bytes from memory map /// </summary> /// <param name="serial">A double precision number.</param> /// <param name="addres">A double precision number.</param> /// <param name="data">A double precision number.</param> /// <param name="timeut">A double precision number.</param> /// <returns> /// Memory Map values from read address request /// </returns> /// <example> /// <code> /// lx.Read(new USBSerial("COM5"), 0, 1, 400) /// </code> /// </example> /// <exception cref="System.TimeoutException">Thrown response Timeout is reached </exception> /// <exception cref="System.IO.InvalidDataException">Thrown when response data or CRC is not valid </exception> /// See <see cref="Read(UInt32 addres, uint data)"/> to add doubles. /// <seealso cref="Write(byte addres, byte[] data)"/> /// <seealso cref="Write(ISerial serial, UInt32 addres, byte[] data, int timeout)"/> public byte[] Read(ISerial serial, UInt32 addres, uint data, int timeout) { /* +------------+----------+----------------------------------------------------------+ * | Byte Index | Field | Notes | * +------------+----------+----------------------------------------------------------+ * | 0 | Header | This field is always 0x25 | * | 1 | Command | 0x80, 0x82, 0x84, 0x86 as detailed in section 4.2 above | * | 2 | Address | Address of first byte to read | * | 3 | Size | Number of bytes to read | * | 4 | Checksum | 2’s complement of sum: header + command + address + data | * +------------+----------+----------------------------------------------------------+ * * Command * ------- * block 0 addres >= 0 & < 256 = 0x80 => 128 * block 1: addres >= 256 & < 512 = 0x82 => 130 * block 2:addres >= 512 & < 768 = 0x84 => 132 * block 3:addres >= 768 = 0x86 => 134 */ uint read_comand = (uint)(128 + ((addres / 256) * 2)); /* Address * ------- * addres then become offset from 256 block * Example: Addres 600 --> block 2 --> offset 600 - 512 = 88; */ uint start_addres = (uint)(addres - ((addres / 256) * 256)); //generate payload woth header, command, addres and data byte[] payload = new byte[] { 0x25, // header (byte)read_comand, (byte)start_addres, (byte)data }; //Addes checksum to payload byte[] stream = checkSum(payload); //Send Lexi Read command thought "serial port" serial.Write(stream, 0, stream.Length); //define response buffer size byte[] rawBuffer = new byte[2]; int response_offest = 0; if (serial.isEcho()) { response_offest = stream.Length; } Array.Resize(ref rawBuffer, (int)(rawBuffer.Length + data + response_offest)); // whait till the response buffer data is available or timeout limit is reached long timeout_limit = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (timeout); while (checkResponseOk(serial, rawBuffer)) { if (DateTimeOffset.Now.ToUnixTimeMilliseconds() > timeout_limit) { if (serial.BytesToRead() <= response_offest) { throw new IOException(); } else { throw new TimeoutException(); } } //Thread.Sleep(100); // await Task.Delay(100); } //read the response buffer serial.Read(rawBuffer, 0, (int)(rawBuffer.Length)); /* * +------------+-------+---------------+--------------------------------------------------------+ * | Byte Index | Field | Value(s) | Notes | * +------------+-------+---------------+--------------------------------------------------------+ * | 0..N-1 | Data | Read from RAM | N = number of bytes specified in Data field of Request | * | N..N+1 | CRC | Calculated | CRC over all data bytes. See section 7.2 | * +------------+-------+---------------+--------------------------------------------------------+ * */ //Get response body from RAW response (clean echo response) byte[] response = new byte[2]; Array.Resize(ref response, (int)(response.Length + data)); Array.Copy(rawBuffer, response_offest, response, 0, response.Length); //Validare CRC ane get Response BUDY return(validateReadResponse(response, data)); }
public async Task Write(ISerial serial, UInt32 addres, byte[] data, int timeout) { int TEST = new Random().Next(0, 999); Utils.PrintDeep(Environment.NewLine + "-------LEXI_WRITE--------| " + TEST + " |--"); Utils.PrintDeep("Lexi.Write = Write + UpdateBuffer + ReadBuffer"); /* * +------------+----------+----------------------------------------------------------+ * | Byte Index | Field | Notes | * +------------+----------+----------------------------------------------------------+ * | 0 | Header | This field is always 0x25 | * | 1 | Command | 0x81, 0x83, 0x85, 0x87 as detailed in section 4.2 above | * | 2 | Address | Address of first byte to write | * | 3 | Size | Number of bytes to write | * | 4 | Checksum | 2’s complement of sum: header + command + address + data | * | 5..4+N | Data | N = number of bytes specified in Data/Size field above | * | 6+N..7+N | CRC | See section 7.2 | * +------------+----------+----------------------------------------------------------+ * * Command * ------- * block 0 addres >= 0 & < 256 = 0x81 => 129 * block 1: addres >= 256 & < 512 = 0x83 => 131 * block 2:addres >= 512 & < 768 = 0x85 => 133 * block 3:addres >= 768 = 0x87 => 135 */ try { uint write_comand = (uint)(129 + ((addres / 256) * 2)); /* Address * ------- * addres then become offset from 256 block * Example: Addres 600 --> block 2 --> offset 600 - 512 = 88; */ uint start_addres = (uint)(addres - ((addres / 256) * 256)); // Data frame { 25 | WriteCmd | Address | BytesToWrite | Checksum }.Length = 5 byte[] payload = new byte[] { 0x25, // header (byte)write_comand, (byte)start_addres, (byte)data.Length }; // Adds checksum to payload byte[] header = checkSum(payload); byte[] crc = BitConverter.GetBytes(calcCRC(data, data.Length)); // Concatenate header, data to write and calculated CRC byte[] stream = new byte[0]; Array.Resize(ref stream, header.Length + data.Length + 2 /*CRC*/); Array.Copy(header, 0, stream, 0, header.Length); Array.Copy(data, 0, stream, header.Length, data.Length); stream[stream.Length - 1] = crc[1]; stream[stream.Length - 2] = crc[0]; Utils.PrintDeep("Lexi.Write.. " + "Stream = Header [ " + "0x25 + " + "WriteCmd 0x" + ( byte )write_comand + " ( " + write_comand + " ) + " + "Address 0x" + ( byte )start_addres + " ( " + start_addres + " ) + " + "NumBytesToWrite 0x" + ( byte )data.Length + " ( " + data.Length + " ) + " + "Checksum 0x" + ( byte )header [header.Length - 1] + " ( " + header [header.Length - 1] + " ) + " + "Data [ " + Utils.ByteArrayToString(data) + " ] + " + "CRC [ " + Utils.ByteArrayToString(crc.Take(2).ToArray()) + " ]"); Utils.PrintDeep("Lexi.Write.. " + Utils.ByteArrayToString(stream).Trim() + " [ Length " + stream.Length + " ]"); // Send Lexi Write command // Stream length is always "5" = 25 + WriteCmd + Address + BytesToWrite + Checksum await serial.Write(stream, 0, stream.Length); Utils.PrintDeep("------BUFFER_START-------"); //define response buffer size byte[] rawBuffer = new byte[0]; int responseOffset = (serial.isEcho()) ? stream.Length : 0; Array.Resize(ref rawBuffer, responseOffset + 2); // CRC that will be recovered Utils.PrintDeep("Lexi.Write.. " + "Echo " + serial.isEcho().ToString().ToUpper() + " | StreamFromMTU = Header x" + header.Length + " + Data x" + data.Length + " + CRC x2 + MTU.CRC x2 = " + rawBuffer.Length + " bytes"); // Whait untill the response buffer data is available or timeout limit is reached int bytesToRead = 0; long timeout_limit = DateTimeOffset.Now.ToUnixTimeMilliseconds() + timeout; await Task.Run(() => { while ((bytesToRead = serial.BytesToRead()) < rawBuffer.Length - 1) { Utils.PrintDeep("Lexi.Write.. BytesToRead: " + bytesToRead + "/" + rawBuffer.Length + " [ " + DateTimeOffset.Now.ToUnixTimeMilliseconds() + " > " + timeout_limit + " ]"); if (DateTimeOffset.Now.ToUnixTimeMilliseconds() > timeout_limit) { int num = serial.BytesToRead(); if (num <= responseOffset) { Utils.PrintDeep("Lexi.Write -> CheckResponseOk IOException"); throw new IOException(); } else { Utils.PrintDeep("Lexi.Write -> CheckResponseOk TimeoutException"); throw new TimeoutException(); } } Thread.Sleep(10); } }); Utils.PrintDeep("Lexi.Read.. BytesRead: " + bytesToRead + " / " + (rawBuffer.Length - 1)); Utils.PrintDeep("------BUFFER_FINISH------"); serial.Read(rawBuffer, 0, rawBuffer.Length); byte[] response = new byte[2]; Array.Copy(rawBuffer, responseOffset, response, 0, response.Length); Utils.PrintDeep("Lexi.Write.." + " RawBuffer " + Utils.ByteArrayToString(rawBuffer) + " | ACK " + Utils.ByteArrayToString(response)); // If first byte of the recovered CRC is 6, everything has gone OK if (response[0] != 0x06) { //throw new LexiWriteException(response); } } catch (Exception e) { throw new LexiWritingException(); } finally { Utils.PrintDeep("----LEXI_WRITE_FINISH----| " + TEST + " |--" + Environment.NewLine); } }
/// <summary> /// Request to read bytes from memory map /// </summary> /// <param name="serial">A double precision number.</param> /// <param name="addres">A double precision number.</param> /// <param name="bytesToRead">A double precision number.</param> /// <param name="timeut">A double precision number.</param> /// <returns> /// Memory Map values from read address request /// </returns> /// <example> /// <code> /// lx.Read(new USBSerial("COM5"), 0, 1, 400) /// </code> /// </example> /// <exception cref="System.TimeoutException">Thrown response Timeout is reached </exception> /// <exception cref="System.IO.InvalidDataException">Thrown when response data or CRC is not valid </exception> /// See <see cref="Read(UInt32 addres, uint data)"/> to add doubles. /// <seealso cref="Write(byte addres, byte[] data)"/> /// <seealso cref="Write(ISerial serial, UInt32 addres, byte[] data, int timeout)"/> public async Task <byte[]> Read(ISerial serial, UInt32 addres, uint bytesToRead, int timeout) { int TEST = new Random().Next(0, 999); Utils.PrintDeep(Environment.NewLine + "--------LEXI_READ-------| " + TEST + " |--"); Utils.PrintDeep("Lexi.Read = Write + UpdateBuffer + Read"); /* +------------+----------+----------------------------------------------------------+ * | Byte Index | Field | Notes | * +------------+----------+----------------------------------------------------------+ * | 0 | Header | This field is always 0x25 | * | 1 | Command | 0x80, 0x82, 0x84, 0x86 as detailed in section 4.2 above | * | 2 | Address | Address of first byte to read | * | 3 | Size | Number of bytes to read | * | 4 | Checksum | 2’s complement of sum: header + command + address + data | * +------------+----------+----------------------------------------------------------+ * * Command * ------- * block 0 addres >= 0 & < 256 = 0x80 => 128 * block 1: addres >= 256 & < 512 = 0x82 => 130 * block 2:addres >= 512 & < 768 = 0x84 => 132 * block 3:addres >= 768 = 0x86 => 134 */ try { uint read_comand = (uint)(128 + ((addres / 256) * 2)); /* Address * ------- * addres then become offset from 256 block * Example: Addres 600 --> block 2 --> offset 600 - 512 = 88; */ uint start_addres = (uint)(addres - ((addres / 256) * 256)); // Data frame { 25 | ReadCmd | Address | BytesToRead | CheckSum }.Length = 5 byte[] payload = new byte[] { 0x25, (byte)read_comand, (byte)start_addres, (byte)bytesToRead }; // Adds checksum to payload byte[] stream = checkSum(payload); Utils.PrintDeep("Lexi.Read -> Write.." + " Address " + start_addres + " | ReadCmd " + read_comand + " | BytesToRead " + bytesToRead + " | TimeOut " + timeout + " | Stream " + Utils.ByteArrayToString(stream) + " [ " + stream.Length + " ]"); // Send Lexi Read command // Stream length is always "5" = 25 + ReadCmd + Address + BytesToRead + Checksum await serial.Write(stream, 0, stream.Length); Utils.PrintDeep("------BUFFER_START-------"); //define response buffer size byte[] rawBuffer = new byte[0]; int headerOffset = (serial.isEcho()) ? stream.Length : 0; Array.Resize(ref rawBuffer, headerOffset + ( int )bytesToRead + 2); // Header + Data + CRC Utils.PrintDeep("Lexi.Read -> Array.Resize.." + " Echo " + serial.isEcho() + " [ " + rawBuffer.Length + " = " + bytesToRead + " + Header " + headerOffset + " + CRC 2 ]"); // Whait untill the response buffer data is available or timeout limit is reached long timeout_limit = DateTimeOffset.Now.ToUnixTimeMilliseconds() + (timeout); await Task.Run(() => { while (checkResponseOk(serial, rawBuffer)) { if (DateTimeOffset.Now.ToUnixTimeMilliseconds() > timeout_limit) { int num = serial.BytesToRead(); Utils.PrintDeep("Lexi.Read -> BytesToRead: " + num); if (num <= headerOffset) { Utils.PrintDeep("Lexi.Read -> CheckResponseOk IOException"); throw new IOException(); } else { Utils.PrintDeep("Lexi.Read -> CheckResponseOk TimeoutException"); throw new TimeoutException(); } } Thread.Sleep(10); } }); Utils.PrintDeep("------BUFFER_FINISH------"); //read the response buffer serial.Read(rawBuffer, 0, rawBuffer.Length); /* * +------------+-------+---------------+--------------------------------------------------------+ * | Byte Index | Field | Value(s) | Notes | * +------------+-------+---------------+--------------------------------------------------------+ * | 0..N-1 | Data | Read from RAM | N = number of bytes specified in Data field of Request | * | N..N+1 | CRC | Calculated | CRC over all data bytes. See section 7.2 | * +------------+-------+---------------+--------------------------------------------------------+ * */ // Removes header byte[] response = new byte[2]; Array.Resize(ref response, response.Length + ( int )bytesToRead); Array.Copy(rawBuffer, headerOffset, response, 0, response.Length); Utils.PrintDeep("Lexi.Read ->" + " CheckCRC " + Utils.ByteArrayToString(response) + " [ " + response.Length + " = BytesToRead " + bytesToRead + " + CRC 2 ]"); // Validates CRC and if everything is ok, returns recovered data return(validateReadResponse(response, bytesToRead)); } catch (Exception e) { throw new LexiReadingException(); } finally { Utils.PrintDeep("----LEXI_READ_FINISH----| " + TEST + " |--" + Environment.NewLine); } }