Ejemplo n.º 1
0
        public static async Task <FrameHeader> ReadHeader(this IDuplexStream stream, CancellationToken cancellationToken = default)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            return((FrameHeader)(await stream.Read(1, cancellationToken)).Single());
        }
Ejemplo n.º 2
0
        private async Task <DataFrame> ReadDataFrame(CancellationToken cancellationToken = default)
        {
            // INS12350-Serial-API-Host-Appl.-Prg.-Guide | 6.2.1 Data frame reception timeout
            // A receiving host or Z-Wave chip MUST abort reception of a Data frame if the reception has lasted for
            // more than 1500ms after the reception of the SOF byte.
            using (var timeoutCancelation = new CancellationTokenSource(ProtocolSettings.DataFrameWaitTime))
            {
                // combine the passed and the timeout cancelationtokens
                using (var linkedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCancelation.Token))
                {
                    // read the length
                    var length = await Stream.ReadByte(linkedCancellation.Token);

                    // read data (payload and checksum)
                    var data = await Stream.Read(length, linkedCancellation.Token);

                    // payload (data without checksum)
                    var payload = data.Take(data.Length - 1).ToArray();

                    // checksum
                    var actualChecksum = data.Last();

                    // calculate required checksum (include length)
                    var expectedChecksum = new byte[] { length }.Concat(payload).CalculateLrc8Checksum();

                    // validate checksum
                    if (actualChecksum != expectedChecksum)
                    {
                        throw new ChecksumException("Checksum failure");
                    }

                    // return dataframe
                    return(new DataFrame((DataFrameType)payload[0], new Payload(payload.Skip(1))));
                }
            }
        }