[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)); } }
/// <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; } } }
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); }
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)); } }); }
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."); } }
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(); }
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(); } }
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);
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); }