private async Task <object> ReadAsync() { //Read a chunk var readBuffer = await _HidDevice.ReadAsync(); TMessageType messageType; //Check to see that this is a valid first chunk var firstByteNot63 = readBuffer[0] != (byte)'?'; var secondByteNot35 = readBuffer[1] != 35; var thirdByteNot35 = readBuffer[2] != 35; if (firstByteNot63 || secondByteNot35 || thirdByteNot35) { var message = $"An error occurred while attempting to read the message from the device. The last written message was a {_LastWrittenMessage?.GetType().Name}. In the first chunk of data "; if (firstByteNot63) { message += "the first byte was not 63"; } if (secondByteNot35) { message += "the second byte was not 35"; } if (thirdByteNot35) { message += "the third byte was not 35"; } throw new ReadException(message, readBuffer, _LastWrittenMessage); } //Looks like the message type is at index 4 var messageTypeInt = readBuffer[4]; if (!Enum.IsDefined(MessageTypeType, (int)messageTypeInt)) { throw new Exception($"The number {messageTypeInt} is not a valid MessageType"); } //Get the message type var messageTypeValueName = Enum.GetName(MessageTypeType, messageTypeInt); messageType = (TMessageType)Enum.Parse(MessageTypeType, messageTypeValueName); //msgLength:= int(binary.BigEndian.Uint32(buf[i + 4 : i + 8])) //TODO: Is this correct? var remainingDataLength = ((readBuffer[5] & 0xFF) << 24) + ((readBuffer[6] & 0xFF) << 16) + ((readBuffer[7] & 0xFF) << 8) + (readBuffer[8] & 0xFF); var length = Math.Min(readBuffer.Length - (FirstChunkStartIndex), remainingDataLength); //This is the first chunk so read from 9-64 var allData = GetRange(readBuffer, FirstChunkStartIndex, length); remainingDataLength -= allData.Length; _InvalidChunksCounter = 0; while (remainingDataLength > 0) { //Read a chunk readBuffer = await _HidDevice.ReadAsync(); //check that there was some data returned if (readBuffer.Length <= 0) { continue; } //Check what's smaller, the buffer or the remaining data length length = Math.Min(readBuffer.Length, remainingDataLength); if (readBuffer[0] != (byte)'?') { if (_InvalidChunksCounter++ > 5) { throw new Exception("messageRead: too many invalid chunks (2)"); } } allData = Append(allData, GetRange(readBuffer, 1, length - 1)); //Decrement the length of the data to be read remainingDataLength -= (length - 1); //Super hack! Fix this! if (remainingDataLength != 1) { continue; } allData = Append(allData, GetRange(readBuffer, length, 1)); remainingDataLength = 0; } var msg = Deserialize(messageType, allData); Logger.Log($"Read: {msg}", null, LogSection); return(msg); }