public byte[] ToByteArray()
        {
            var outputBuffer = new WireBuffer(Body.Data.Length + 8);

            // For general protocol doc this is written against, see https://github.com/madcowswe/ODrive/blob/1294ddff1dd0619e9f098ce12ca0936670a5b405/docs/protocol.md
            // Bytes 0, 1 Sequence number, MSB = 0
            // Bytes 2, 3 Endpoint ID
            // Bytes 4, 5 Expected response size
            // Bytes 6 to N-3 Payload
            // Bytes N-2, N-1 signature, depends on endpoint

            outputBuffer
            .Write(EncodedSequenceNumber)
            .Write(EncodedEndpointID)
            .Write(ExpectedResponseSize)
            .Write(Body.Data)
            .Write(Signature);

            return(outputBuffer.Data);
        }
        public async Task <byte[]> RequestBufferSegment(
            uint payloadOffset = 0,
            CancellationToken parentCancellationToken = default(CancellationToken),
            Policy requestPolicy = null)
        {
            var policyToUse = requestPolicy ?? StandardTimeoutWaitAndRetryPolicy.Value;

            return(await policyToUse.ExecuteAsync(async cancellationToken =>
            {
                var taskCompletionSource = new TaskCompletionSource <byte[]>();

                byte[] cumulativeResponse = new byte[0];

                var request = new Request(
                    sequenceNumber: sequenceCounter.NextValue(),
                    endpointID: 0,
                    expectedResponseSize: 32,
                    requestACK: true,
                    populateBody: () =>
                {
                    var wireBuffer = new WireBuffer(4);
                    wireBuffer.Write(payloadOffset);
                    return wireBuffer;
                },
                    responseCallback: res =>
                {
                    var responseBytes = res.Body.Data;
                    taskCompletionSource.SetResult(responseBytes);
                },
                    signature: Config.USB_PROTOCOL_VERSION,
                    cancellationToken: cancellationToken
                    );

                SendRequest(request);

                return await taskCompletionSource.Task.ConfigureAwait(false);
            }, parentCancellationToken).ConfigureAwait(false));
        }
        public async Task <T> RequestResponse <T>(
            ushort endpointID,
            T value,
            CancellationToken parentCancellationToken = default(CancellationToken),
            Policy requestPolicy = null)
        {
            var policyToUse = requestPolicy ?? StandardTimeoutWaitAndRetryPolicy.Value;

            return(await policyToUse.ExecuteAsync(async cancellationToken =>
            {
                var taskCompletionSource = new TaskCompletionSource <T>();

                var dataSize = (ushort)Marshal.SizeOf(typeof(T));

                WireBuffer requestBuffer = null;
                requestBuffer = new WireBuffer(dataSize);
                requestBuffer.Write(value);

                var request = new Request(
                    sequenceNumber: sequenceCounter.NextValue(),
                    endpointID: endpointID,
                    expectedResponseSize: dataSize,
                    requestACK: true,
                    populateBody: () => requestBuffer,
                    responseCallback: res =>
                {
                    var responseData = res.Body.Read <T>();
                    taskCompletionSource.SetResult(responseData);
                },
                    signature: SchemaChecksum ?? Config.USB_PROTOCOL_VERSION,
                    cancellationToken: cancellationToken
                    );

                SendRequest(request);

                return await taskCompletionSource.Task.ConfigureAwait(false);
            }, parentCancellationToken).ConfigureAwait(false));
        }