Ejemplo n.º 1
0
        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);
        }