Пример #1
0
        private Task <ViscaPacket> SendAsync(CancellationToken cancellationToken, params byte[] packet)
        {
            var effectiveToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, new CancellationTokenSource(CommandTimeout).Token).Token;
            var request        = ViscaPacket.FromBytes(packet, 0, packet.Length);

            return(client.SendAsync(request, effectiveToken));
        }
Пример #2
0
        internal async Task <ViscaPacket> ReadAsync(Stream stream, CancellationToken cancellationToken)
        {
            while (true)
            {
                if (FindEnd() is int count)
                {
                    return(Consume(count));
                }
                if (size == buffer.Length)
                {
                    // TODO: Should our buffer be smaller?
                    throw new ViscaProtocolException($"Read {size} bytes without a reaching the end of a VISCA packet");
                }
                using (var registration = cancellationToken.Register(() => stream.Close()))
                {
                    int bytesRead = await stream.ReadAsync(buffer, size, buffer.Length - size).ConfigureAwait(false);

                    if (bytesRead == 0)
                    {
                        throw new ViscaProtocolException("Reached end of VISCA stream");
                    }
                    size += bytesRead;
                }
            }

            int?FindEnd()
            {
                for (int i = 0; i < size; i++)
                {
                    if (buffer[i] == 0xff)
                    {
                        // Include the trailing byte
                        return(i + 1);
                    }
                }
                return(null);
            }

            ViscaPacket Consume(int count)
            {
                // Exclude the trailing byte from the packet
                var packet = ViscaPacket.FromBytes(buffer, 0, count - 1);

                size -= count;
                // Shift the content of the array if we need to.
                // (Alternatively, we could construct the packet from middle of the byte array,
                // and only shift when we got near the end of the buffer. It really shouldn't matter much though.)
                if (size != 0)
                {
                    Buffer.BlockCopy(buffer, count, buffer, 0, size);
                }
                return(packet);
            }
        }
Пример #3
0
        async Task <ViscaPacket> IViscaClient.SendAsync(ViscaPacket request, CancellationToken cancellationToken)
        {
            bool reconnect = true;
            await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                await SendPacketAsync(request, cancellationToken).ConfigureAwait(false);

                while (true)
                {
                    ViscaPacket response = await ReceivePacketAsync(cancellationToken).ConfigureAwait(false);

                    if (response.Length < 2)
                    {
                        throw new ViscaProtocolException($"Received packet of length {response.Length} from VISCA endpoint");
                    }
                    switch (response.GetByte(1) >> 4)
                    {
                    // Command received
                    case 4:
                        continue;

                    // Success
                    case 5:
                        reconnect = false;
                        return(response);

                    // Error reported by device
                    case 6:
                        throw new ViscaResponseException($"Error reported by VISCA interface. Error data: {response}");

                    // VISCA protocol violation
                    default:
                        throw new ViscaProtocolException($"Invalid packet returned from VISCA interface. Error data: {response}");
                    }
                }
            }
            finally
            {
                try
                {
                    if (reconnect)
                    {
                        await ReconnectAsync(cancellationToken).ConfigureAwait(false);
                    }
                }
                finally
                {
                    semaphore.Release();
                }
            }
        }
Пример #4
0
        async Task <ViscaPacket> IViscaClient.SendAsync(ViscaPacket request, CancellationToken cancellationToken)
        {
            await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                if (request.GetByte(0) != 0x81 || request.Length < 5)
                {
                    return(SyntaxError);
                }
                return(request.GetByte(1) switch
                {
                    0x01 => await ExecuteCommand(request).ConfigureAwait(false),
                    0x09 => ExecuteQuery(request),
                    _ => SyntaxError
                });
            }
Пример #5
0
 /// <summary>
 /// Sends a single packet to the VISCA endpoint.
 /// </summary>
 /// <param name="packet">The packet to send to the endpoint.</param>
 /// <param name="cancellationToken">A token to indicate that the method has been cancelled.</param>
 /// <returns>A task representing the asynchronous operation.</returns>
 protected abstract Task SendPacketAsync(ViscaPacket packet, CancellationToken cancellationToken);