[Timeout(2000)] // We abort the test after timeout. This tests the blocking behavior in ReadAsync and the test will fail if ReadAsync blocks.
        public async Task WriteAsync()
        {
            using (var serialPortStreamWrite = new SerialPortStream("COM1", 9600, 8, Parity.None, StopBits.One))
                using (var serialPortStreamRead = new SerialPortStream("COM2", 9600, 8, Parity.None, StopBits.One))
                {
                    serialPortStreamWrite.Open();
                    serialPortStreamRead.Open();

                    var buffer   = new byte[1024];
                    var readTask = Task.Run(async() => await serialPortStreamRead.ReadAsync(buffer, 0, buffer.Length));

                    var bytes = new byte[] { 0x01, 0x02, 0x03 };
                    await serialPortStreamWrite.WriteAsync(bytes, 0, bytes.Length);

                    await serialPortStreamWrite.FlushAsync();

                    // ReadAsync blocks here even if something gets written and flushed to the underlying COM device.
                    // Fails for netcoreapp3.1, works with net472
                    await readTask;

                    Assert.That(buffer[0], Is.EqualTo(0x01));
                    Assert.That(buffer[1], Is.EqualTo(0x02));
                    Assert.That(buffer[2], Is.EqualTo(0x03));
                }
        }
示例#2
0
        /// <summary>
        /// Main serial listening loop
        /// </summary>
        private void SerialPortListener()
        {
            //New Cancellation Token
            _cancellationToken = new CancellationTokenSource();

            Task.Run(async() =>
            {
                try
                {
                    while (!_cancellationToken.IsCancellationRequested)
                    {
                        //Throw Exception when serial port is disconnected
                        bool carrierDetect = _serialPort.CDHolding;

                        //Data received?
                        //Unpluging serial USB does not throw an error
                        //_serialPort.BytesToRead return 0...so SerialPortListener is still working
                        int byteToRead = _serialPort.BytesToRead;
                        if (byteToRead > 0)
                        {
                            var receiveBuffer = new byte[_serialPort.ReadBufferSize];

                            //Clear buffer
                            //Array.Clear(buffer, 0, buffer.Length);
                            int numBytesRead = await _serialPort.ReadAsync(receiveBuffer, 0, receiveBuffer.Length, _cancellationToken.Token).ConfigureAwait(false);

                            var bytesReceived = new byte[numBytesRead];

                            Array.Copy(receiveBuffer, bytesReceived, numBytesRead);

                            if (bytesReceived.ToArray().Where(t => t == Encoding.ASCII.GetBytes(FrameBase.FRAME_END_DELIMITER)[0]).Count() != 0)
                            {
                                string dataReceived = System.Text.Encoding.UTF8.GetString(bytesReceived.ToArray());

                                //Throw event here!
                                OnDataReceived(dataReceived);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    _logger.Error(e, "Exception occured in SerialPortListener");

                    OnSerialPortErrorOccured();

                    //Handle any error on serial port here...
                    Dispose();
                }
            }).ConfigureAwait(false);
        }
        private async Task MoveFinished()
        {
            byte[] buffer = new byte[1024];
            while (true)
            {
                await _serial.ReadAsync(buffer);

                var response = System.Text.Encoding.Default.GetString(buffer);
                if (response.Contains("ok"))
                {
                    _serial.DiscardOutBuffer();
                    return;
                }
            }
        }
示例#4
0
        private async Task <byte[]> ReadCurrentReceiveBufferAsync(int numberOfBytes)
        {
            var result     = new byte[numberOfBytes];
            var retrieved  = 0;
            var retryCount = 0;

            while (retrieved < numberOfBytes && retryCount++ < 4)
            {
                retrieved += await serialPort.ReadAsync(result, retrieved, numberOfBytes - retrieved);
            }

            if (retrieved < numberOfBytes)
            {
                logger.Info("Ended up reading short (expected {0} bytes, got only {1})...",
                            numberOfBytes, retrieved);
            }
            return(result);
        }
示例#5
0
        internal void TailSerialPortStream(SerialPortStream stream)
        {
            Task.Run(async() =>
            {
                bool exceptionCaught = false;
                while (!exceptionCaught)
                {
                    // Check if we can continue to tail.
                    this.keepTailing.WaitOne();

                    string newOutput;
                    try
                    {
                        newOutput = await stream.ReadAsync();
                        newOutput = newOutput.Replace("\n", "\r\n");
                    }
                    catch (TokenResponseException e)
                    {
                        newOutput = "Reading from serial port failed - session timed out " +
                                    $"({e.Error.ErrorDescription})";
                        exceptionCaught = true;
                    }
                    catch (Exception e)
                    {
                        newOutput       = $"Reading from serial port failed: {e.Unwrap().Message}";
                        exceptionCaught = true;
                    }

                    // By the time we read the data, the form might have begun closing. In this
                    // case, updating the UI would cause an exception.
                    if (!this.formClosing)
                    {
                        BeginInvoke((Action)(() => this.log.AppendText(newOutput)));
                    }

                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }
            });
        }
示例#6
0
        async Task SimpleCommandTxRxAsync(ISweepCommand cmd)
        {
            var buffer = new byte[cmd.ExpectedAnswerLength];

            // throwaway stuff in the RX buffer!
            serialPort.DiscardInBuffer();

            // TX then RX
            await serialPort.WriteAsync(cmd.Command.Select(x => (byte)x).ToArray(), 0, cmd.Command.Length);
            var bytesRead = await serialPort.ReadAsync(buffer, 0, cmd.ExpectedAnswerLength);

            if(bytesRead == cmd.ExpectedAnswerLength)
            {
                cmd.ProcessResponse(buffer.Select(x => (char)x).ToArray());
            }
            else
            {
                throw new SweepProtocolErrorException(
                    $"Answer was {bytesRead} bytes long instead of expected {cmd.ExpectedAnswerLength}",
                    buffer.Select(x => (char)x).ToArray());
            }           
        }
        static async Task Main(string[] args)
        {
            Console.WriteLine("Start");

            using (var serialPortStreamWrite = new SerialPortStream("COM1", 9600, 8, Parity.None, StopBits.One))
                using (var serialPortStreamRead = new SerialPortStream("COM2", 9600, 8, Parity.None, StopBits.One))
                {
                    serialPortStreamWrite.Open();
                    serialPortStreamRead.Open();

                    Console.WriteLine("Serial Port Opened");

                    var buffer   = new byte[1024];
                    var readTask = Task.Run(async() => await serialPortStreamRead.ReadAsync(buffer, 0, buffer.Length));

                    Console.WriteLine("Wait for write. Enter any key.");
                    Console.ReadKey();


                    var bytes = new byte[] { 0x01, 0x02, 0x03 };

                    Console.WriteLine("Write started");
                    await serialPortStreamWrite.WriteAsync(bytes, 0, bytes.Length);

                    await serialPortStreamWrite.FlushAsync();

                    Console.WriteLine("Write finished");


                    Console.WriteLine("Awaiting read...");

                    await readTask;

                    Console.WriteLine($"Buffer: {buffer[0]}, {buffer[1]}, {buffer[2]}");

                    Console.WriteLine("Finished.");
                }
        }
示例#8
0
        private async Task SerialOpen()
        {
            byte[] buffer = new byte[128];
            if (_serial.IsOpen == false)
            {
                Logger.Log("Opening serial port...");
                _serial.Open();
            }
            Logger.Log("Awaiting handshake...");
            while (true)
            {
                await _serial.ReadAsync(buffer);

                var response = System.Text.Encoding.Default.GetString(buffer);
                if (response.Contains("start"))
                {
                    Logger.Log("Handshake successful...");
                    break;
                }
                await Task.Delay(250);
            }
            _serial.DiscardOutBuffer();
        }
示例#9
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            var options = _options.Value;

            _logger.LogInformation("Opening {SerialPort}", options.Port);

            using (var port = new SerialPortStream(options.Port, options.Baud))
            {
                port.Open();

                // Clear Status
                var cls = Encoding.ASCII.GetBytes("*CLS\n");
                await port.WriteAsync(cls, 0, cls.Length);

                // §3.5.10
                var formatPacked = Encoding.ASCII.GetBytes("FORMat PACKed\n");
                await port.WriteAsync(formatPacked, 0, formatPacked.Length);

                // §3.5.17
                var lterEoi = Encoding.ASCII.GetBytes("SYSTem:COMMunicate:GPIB:LTERminator EOI\n");
                await port.WriteAsync(lterEoi, 0, lterEoi.Length);

                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        await _wait.WaitAsync(cancellationToken);
                    }
                    catch (OperationCanceledException)
                    {
                    }

                    if (_queue.TryDequeue(out var item))
                    {
                        if (item.CancellationToken.IsCancellationRequested)
                        {
                            continue;
                        }

                        _logger.LogDebug("Sending {Request}", Encoding.ASCII.GetString(item.Request));

                        await port.WriteAsync(item.Request, 0, item.Request.Length, cancellationToken);

                        await port.FlushAsync(cancellationToken);

                        if (item.ExpectResponse)
                        {
                            var buffer = ArrayPool <byte> .Shared.Rent(1024);

                            var offset = 0;

                            try
                            {
                                var length = -1;

                                while (length == -1 || offset < length)
                                {
                                    var oldOffset = offset;
                                    var increased = await port.ReadAsync(buffer, offset, buffer.Length - offset, cancellationToken);

                                    offset += increased;

                                    if (offset > 0 && buffer[offset] == '#' && BlockData.TryDecodeLength(buffer.AsSpan().Slice(0, offset), out var decodedLength))
                                    {
                                        length = decodedLength;
                                    }
                                    else
                                    {
                                        var relativeIndex = buffer.AsSpan().Slice(oldOffset, increased).IndexOf((byte)'\n');

                                        if (relativeIndex >= 0)
                                        {
                                            length = oldOffset + relativeIndex + 1;
                                        }
                                    }
                                }

                                var response = buffer.AsSpan().Slice(0, length).ToArray();

                                _logger.LogDebug("Received {ResponseBytes} bytes: {Response}", response.Length, Encoding.ASCII.GetString(response));

                                item.TaskCompletionSource.SetResult(response);
                            }
                            finally
                            {
                                ArrayPool <byte> .Shared.Return(buffer);
                            }
                        }
                        else
                        {
                            item.TaskCompletionSource.SetResult(null);
                        }
                    }
                }

                port.Close();
            }
        }
示例#10
0
        private async Task <EnOceanPacket> ReadFrameInternal()
        {
            try
            {
                var firstChar = (byte)_stream.ReadByte();
                await Task.Delay(100);

                if (firstChar == EnOcean.SyncByte)
                {
                    var dataLen     = new byte[2];
                    var dataLenRead = await _stream.ReadAsync(dataLen, 0, 2);

                    if (dataLenRead == 2)
                    {
                        var dataLenShort = BitConverter.ToUInt16(dataLen.Reverse().ToArray(), 0);

                        var optLen     = (byte)_stream.ReadByte();
                        var packetType = (byte)_stream.ReadByte();
                        var crc8Header = (byte)_stream.ReadByte();

                        var header = new byte[] { firstChar, dataLen[0], dataLen[1], optLen, packetType, crc8Header };

                        var           data       = new byte[dataLenShort];
                        Memory <byte> dataMemory = new Memory <byte>(data);
                        var           read       = await _stream.ReadAsync(dataMemory);

                        if (read == dataLenShort)
                        {
                            var           optData   = new byte[optLen];
                            Memory <byte> optMemory = new Memory <byte>(optData);

                            read = await _stream.ReadAsync(optMemory);

                            if (read == optLen)
                            {
                                var crcData = (byte)_stream.ReadByte();
                                var packet  = EnOceanPacket.Parse(new Memory <byte>(header), dataMemory, optMemory, crcData);

                                Logger.Logger.Instance.LogHexIn(packet.RawData);
                                return(packet);
                            }
                        }
                        else
                        {
                            Logger.Logger.Instance.LogDebug($"In buffer length to short {read}/{dataLenShort}");
                        }
                    }
                    else
                    {
                        Logger.Logger.Instance.LogDebug($"Could not read length of package");
                    }
                }
                else
                {
                    Logger.Logger.Instance.LogDebug($"Invalid sync byte received {firstChar}");
                    if (_stream.BytesToRead > 0)
                    {
                        return(await ReadFrameInternal());
                    }
                }
            }
            catch (IOException ioe)
            {
                Logger.Logger.Instance.LogError($"Could not read frame {ioe}", ioe);
                Close();
                Thread.Sleep(100);
                Open();
            }
            catch (Exception e)
            {
                Logger.Logger.Instance.LogError($"Could not read frame {e}", e);
            }
            return(null);
        }
 public Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
 _serialPort?.ReadAsync(buffer, offset, count, cancellationToken);
示例#12
0
        private async Task <MBusFrame> ReadFrameInternal()
        {
            try
            {
                int firstChar = _stream.ReadByte();

                if (firstChar == MBus.ShortFrameStart)
                {
                    Logger.LogDebug("Start parsing short frame...");
                    Thread.Sleep(100);
                    byte[] shortFrame = new byte[5];
                    shortFrame[0] = (byte)firstChar;
                    var bytesRead = await _stream.ReadAsync(shortFrame, 1, 4);

                    if (bytesRead != 4)
                    {
                        Logger.LogDebug($"Could not parse short frame (read bytes {bytesRead}/4)");
                        return(null);
                    }

                    Logger.LogDebug("Short frame in...");
                    Logger.LogHexIn(shortFrame);

                    var frame = MBusFrame.FromByteArray(MBusFrameType.ShortFrame, Logger, shortFrame);

                    return(frame);
                }
                if (firstChar == MBus.SingleCharFrame)
                {
                    Logger.LogDebug("Ack frame in...");
                    return(new AckFrame());
                }

                if (firstChar == MBus.ControlFrameLongFrameStart)
                {
                    Logger.LogDebug("Start parsing long frame...");
                    Thread.Sleep(200);

                    byte[] headerBuffer = new byte[4];
                    headerBuffer[0] = (byte)firstChar;
                    var bytesRead = await _stream.ReadAsync(headerBuffer, 1, 3);

                    Logger.LogHexIn(headerBuffer);

                    if (bytesRead != 3)
                    {
                        Logger.LogDebug($"Could not read header...read {bytesRead}/3");
                        return(null);
                    }

                    if (headerBuffer[0] == 0x68 && headerBuffer[0] == headerBuffer[3] &&
                        headerBuffer[1] == headerBuffer[2])
                    {
                        int    lengthToRead = headerBuffer[1] + 2; //read with checksum and stop byte
                        byte[] data         = new byte[lengthToRead];
                        var    dataMemory   = new Memory <byte>(data);

                        bytesRead = await _stream.ReadAsync(dataMemory);

                        Logger.LogHexIn(dataMemory);

                        if (bytesRead != lengthToRead)
                        {
                            Logger.LogDebug($"Invalid length of read data...({bytesRead}/{lengthToRead})");
                            return(null); //invalid length of data read
                        }

                        if (data[data.Length - 1] != 0x16)
                        {
                            Logger.LogDebug("Invalid stop byte...");
                            return(null); //invalid stop byte
                        }



                        var packageType = headerBuffer[2] == 3 ? MBusFrameType.ControlFrame : MBusFrameType.LongFrame;
                        return(MBusFrame.FromSpan(packageType, Logger, headerBuffer.AsSpan(), dataMemory.Span));
                    }
                }
            }
            catch (IOException ioe)
            {
                Logger.LogError($"Could not read frame {ioe}", ioe);
                Close();
                Thread.Sleep(100);
                Open();
            }
            catch (Exception e)
            {
                Logger.LogError($"Could not read frame {e}", e);
            }
            return(null);
        }