### Install libnserial package on Ubuntu
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/BUILD.md
Use this command to install the libnserial package on Ubuntu systems. Ensure you have the correct version number for your distribution.
```bash
# apt install libnserial_1.1.4-0ubuntu1~focal1_amd64.deb
```
--------------------------------
### Build and Install SerialPortStream Support Library on Linux
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/README.md
Steps to build and install the native support library for Linux system-wide using CMake and make. This method installs the library to the system's default library paths.
```sh
cd serialportstream/dll/serialunix
mkdir mybuild
cd mybuild
cmake .. && make
sudo make install
```
--------------------------------
### Serial Port Configuration Example
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Configure serial port parameters such as BaudRate, DataBits, StopBits, Parity, and Handshake. Buffer sizes must be set before opening the port. This example demonstrates setting various properties including flow control and buffer tuning.
```csharp
using RJCP.IO.Ports;
using var serial = new SerialPortStream();
serial.PortName = "COM3";
serial.BaudRate = 57600;
serial.DataBits = 8;
serial.StopBits = StopBits.One;
serial.Parity = Parity.Even;
serial.ParityReplace = 0x00; // Replace bad bytes with 0x00 (0 = disable)
serial.Handshake = Handshake.Rts; // RTS/CTS hardware flow control
// serial.Handshake = Handshake.XOn; // XON/XOFF software flow control
// serial.Handshake = Handshake.RtsXOn; // Both
// serial.Handshake = Handshake.Dtr; // DTR/DSR (uncommon)
serial.DtrEnable = true;
serial.RtsEnable = true;
serial.TxContinueOnXOff = false; // Pause TX when XOFF received
serial.DiscardNull = false; // Keep null bytes
// Buffer tuning (must be before Open)
serial.ReadBufferSize = 1024 * 1024; // 1 MB receive buffer
serial.WriteBufferSize = 128 * 1024; // 128 KB transmit buffer
serial.DriverInQueue = 4096; // Driver-level in-queue hint
serial.DriverOutQueue = 4096; // Driver-level out-queue hint
serial.ReceivedBytesThreshold = 1; // Fire DataReceived after 1+ bytes
serial.Open();
Console.WriteLine(serial.ToString());
// COM3:57600,8,E,1,to=off,xon=off,idsr=off,icts=hs,odtr=on,orts=hs
```
--------------------------------
### Build dll/serialunix Locally on Ubuntu
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/BUILD.md
Installs Google Test and Doxygen, then executes the build script. Ensure you are using Ubuntu 16.04 or later.
```shell
sudo apt install libgtest-dev
sudo apt install doxygen
./build.sh
```
--------------------------------
### Clone and Build GoogleTest Framework
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/README.cygwin.md
Clone the GoogleTest framework from GitHub, create a build directory, configure with CMake, and install it. This is a prerequisite for building the serialunix package with unit tests.
```sh
$ git clone https://github.com/google/googletest.git
$ mkdir gtestbuild
$ cd gtestbuild
$ cmake ../googletest
$ make
$ make install
```
--------------------------------
### Modem / Pin Status Properties Example
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Read modem line states such as CTS, DSR, CD, and Ring Indicator while the serial port is open. This example also shows how to send a break signal by manipulating the BreakState property.
```csharp
using RJCP.IO.Ports;
using System;
using var serial = new SerialPortStream("COM3", 9600);
serial.Open();
Console.WriteLine($"CTS: {serial.CtsHolding}"); // Clear-To-Send
Console.WriteLine($"DSR: {serial.DsrHolding}"); // Data-Set-Ready
Console.WriteLine($"CD: {serial.CDHolding}"); // Carrier-Detect
Console.WriteLine($"Ring: {serial.RingHolding}"); // Ring Indicator
// Send a break signal for ~300 ms
serial.BreakState = true;
System.Threading.Thread.Sleep(300);
serial.BreakState = false;
```
--------------------------------
### Find and Link nserial Library with CMake
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/README.cmake.md
Use this CMake configuration to find the nserial package and link its libraries to your executable. Ensure nserial is installed via its config file.
```cmake
cmake_minimum_required(VERSION 2.8)
project(helloworld)
add_executable(helloworld hello.c)
find_package(Threads REQUIRED)
find_package(nserial CONFIG REQUIRED)
include_directories(${nserial_INCLUDE_DIRS})
target_link_libraries(helloworld ${nserial_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
```
--------------------------------
### Configure Logging via app.config (.NET Framework)
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Example of configuring TraceSource for SerialPortStream logging in .NET Framework applications using app.config. Ensure the switchValue is set to 'Verbose' for detailed diagnostics.
```xml
```
--------------------------------
### Basic C Program to Get Serial Version
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/README.cmake.md
A simple C program that includes the nserial library and prints its version string. This demonstrates basic integration with the library.
```c
#include
#include
#include
void main(void)
{
printf("Version: %s\n", serial_version());
}
```
--------------------------------
### Build SerialPortStream Support Library on Linux
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/README.md
Instructions for cloning the repository and building the native support library for Linux using GCC and CMake. Ensure you have a compatible compiler and cmake installed.
```sh
git clone https://github.com/jcurl/serialportstream.git
cd serialportstream/dll/serialunix
./build.sh
```
--------------------------------
### Enumerate Serial Ports
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Demonstrates how to get a list of available serial port names using GetPortNames() and richer descriptions including device details using GetPortDescriptions() via WMI.
```csharp
using RJCP.IO.Ports;
using System;
var probe = new SerialPortStream();
// Raw names
foreach (string name in probe.GetPortNames())
{
Console.WriteLine($"Port: {name}");
// Output: Port: COM1
// Port: COM3
}
// Rich descriptions
foreach (PortDescription desc in probe.GetPortDescriptions())
{
Console.WriteLine($"{desc.Port}: {desc.Description} [{desc.Manufacturer}]");
// Output: COM3: USB Serial Device (COM3) [Microsoft]
}
```
--------------------------------
### Configure WinSerialPortStream with Native Settings
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
This example shows how to use WinSerialPortStream to access and modify low-level Win32 COMMTIMEOUTS settings. This is particularly useful for drivers that require specific WriteTotalTimeoutConstant behavior. The code is marked with SupportedOSPlatform("windows").
```csharp
using RJCP.IO.Ports;
using RJCP.IO.Ports.Serial;
using System;
using System.Runtime.Versioning;
[SupportedOSPlatform("windows")]
static void OpenWithWinSettings()
{
using var serial = new WinSerialPortStream("COM3", 115200, 8, Parity.None, StopBits.One);
// Access Windows-specific COMMTIMEOUTS settings
IWinNativeSettings settings = serial.Settings;
settings.ReadIntervalTimeout = 0; // ms between bytes (0 = disabled)
settings.ReadTotalTimeoutMultiplier = 0; // ms × bytes
settings.ReadTotalTimeoutConstant = 0; // ms constant (0+0 = infinite)
settings.WriteTotalTimeoutMultiplier = 0;
settings.WriteTotalTimeoutConstant = 0; // 0 = no driver-level write timeout
serial.Open();
Console.WriteLine($"Version: {serial.Version}");
serial.WriteLine("AT");
string response = serial.ReadLine();
Console.WriteLine($"Response: {response}");
}
```
--------------------------------
### Get List of COM Ports
Source: https://github.com/jcurl/rjcp.dll.serialportstream/wiki/Getting-a-List-of-Serial-Ports-with-SerialPortStream
Use this method to get a list of available COM port names, compatible with the Microsoft implementation. Ensure System.Diagnostics is imported.
```csharp
using System.Diagnostic;
foreach (string c in SerialPortStream.GetPortNames()) {
Trace.WriteLine("GetPortNames: " + c);
}
```
--------------------------------
### Configure Serial Port with StopBits Enum
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
This example demonstrates configuring a SerialPortStream with a specific number of stop bits using the StopBits enum. Available options are One, One5, and Two.
```csharp
// RJCP.IO.Ports.StopBits
// One = 0 — 1 stop bit (most common)
// One5 = 1 — 1.5 stop bits
// Two = 2 — 2 stop bits
var serial = new SerialPortStream("COM3", 9600, 8, Parity.None, StopBits.Two);
```
--------------------------------
### Console Output of Parity Error (Chipset FAIL)
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/README.linux.md
Example console output demonstrating how a parity error is reported by non-compliant chipsets, marking multiple bytes as incorrect.
```console
0000030: 3031 3233 3435 3637 3839 ff00 3aff 003b 0123456789..:..;
0000040: ff00 3cff 003d ff00 3eff 003f ff00 40ff ..<..=..>..?..@.
0000050: 0041 ff00 42ff 0043 ff00 44ff 0045 4647 .A..B..C..D..EFG
```
--------------------------------
### SerialPortStream.Open / OpenDirect / Close / Dispose
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Explains how to open, open directly, close, and dispose of a SerialPortStream instance. Opening applies settings and starts monitoring, OpenDirect skips settings, Close stops I/O, and Dispose releases resources.
```APIDOC
## SerialPortStream.Open / OpenDirect / Close
`Open()` applies the configured settings to the driver, then starts a background monitoring thread. `OpenDirect()` skips the settings-apply step, useful for virtual COM ports. `Close()` stops I/O but leaves read-buffer data readable. `Dispose()` releases all resources.
```csharp
using RJCP.IO.Ports;
using System;
using var serial = new SerialPortStream("COM3", 115200, 8, Parity.None, StopBits.One);
serial.ReadTimeout = 2000; // ms
serial.WriteTimeout = 2000;
serial.Open();
Console.WriteLine($"Port open: {serial.IsOpen}"); // True
// For virtual/USB serial ports that ignore DCB state:
// serial.OpenDirect();
serial.Close();
Console.WriteLine($"Port open: {serial.IsOpen}"); // False
// Can re-open after Close
serial.Open();
serial.Dispose(); // Also closes if open; cannot be reopened after Dispose
```
```
--------------------------------
### Open, Close, and Dispose SerialPortStream
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Shows how to open, close, and dispose of a SerialPortStream. Open() applies settings and starts monitoring, OpenDirect() skips settings, Close() stops I/O but keeps buffer data readable, and Dispose() releases all resources.
```csharp
using RJCP.IO.Ports;
using System;
using var serial = new SerialPortStream("COM3", 115200, 8, Parity.None, StopBits.One);
serial.ReadTimeout = 2000; // ms
serial.WriteTimeout = 2000;
serial.Open();
Console.WriteLine($"Port open: {serial.IsOpen}"); // True
// For virtual/USB serial ports that ignore DCB state:
// serial.OpenDirect();
serial.Close();
Console.WriteLine($"Port open: {serial.IsOpen}"); // False
// Can re-open after Close
serial.Open();
serial.Dispose(); // Also closes if open; cannot be reopened after Dispose
```
--------------------------------
### Console Output of Parity Error (Chipset PASS)
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/README.linux.md
Example console output showing the expected behavior of a compliant chipset (like 16550A) where only the directly affected byte is marked as incorrect.
```console
0000030: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f 0123456789:;<=>?
0000040: 4041 4243 ff00 4445 4647 4849 4a4b 4c4d @ABC..DEFGHIJKLM
0000050: 4e4f 5051 5253 5455 5657 5859 5a5b 5c5d NOPQRSTUVWXYZ[\ ]
```
--------------------------------
### Configure Serial Port with Parity Enum
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
This example shows how to configure a SerialPortStream with a specific parity setting using the Parity enum. The enum defines options for parity checking: None, Odd, Even, Mark, and Space.
```csharp
// RJCP.IO.Ports.Parity
// None = 0 — No parity checking
// Odd = 1 — Parity bit set so total 1-bits is odd
// Even = 2 — Parity bit set so total 1-bits is even
// Mark = 3 — Parity bit always 1
// Space= 4 — Parity bit always 0
var serial = new SerialPortStream("COM3", 9600, 7, Parity.Even, StopBits.One);
```
--------------------------------
### ErrorReceived Event Handling Example
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Handle the ErrorReceived event to be notified of communication errors reported by the driver. This example checks for common error flags such as RXOver, Overrun, Parity, Frame, and TXFull.
```csharp
using RJCP.IO.Ports;
using System;
using var serial = new SerialPortStream("COM3", 9600);
serial.ErrorReceived += (sender, e) =>
{
if ((e.EventType & SerialError.RXOver) != 0) Console.WriteLine("RX buffer near full (80%)");
if ((e.EventType & SerialError.Overrun) != 0) Console.WriteLine("Driver overrun — bytes lost!");
if ((e.EventType & SerialError.RXParity) != 0) Console.WriteLine("Parity error detected");
if ((e.EventType & SerialError.Frame) != 0) Console.WriteLine("Framing error detected");
if ((e.EventType & SerialError.TXFull) != 0) Console.WriteLine("TX buffer full");
};
serial.Open();
Console.ReadLine();
```
--------------------------------
### Build Release Mode
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/BUILD.md
Builds the project in Release mode. This is unsigned and useful for testing.
```cmd
PS1> dotnet build -c Release
```
--------------------------------
### Execute Unit Tests on Linux
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/BUILD.md
Run this command in the project directory to execute unit tests on a Linux environment.
```bash
$ dotnet test
```
--------------------------------
### Read Current Port Settings
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Explains how to use GetPortSettings() to temporarily open a port, read its current driver configuration (DCB settings), and then close it. This is useful for discovering the OS-level configuration before applying new settings.
```csharp
using RJCP.IO.Ports;
using System;
var serial = new SerialPortStream();
serial.PortName = "COM3";
// Reads current driver state without setting any properties
serial.GetPortSettings();
Console.WriteLine($"Current baud: {serial.BaudRate}"); // e.g. 9600
Console.WriteLine($"Current parity: {serial.Parity}"); // e.g. None
Console.WriteLine($"Data bits: {serial.DataBits}"); // e.g. 8
Console.WriteLine($"Stop bits: {serial.StopBits}"); // e.g. One
```
--------------------------------
### Run SerialUnix Unit and Component Tests
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/README.cygwin.md
Navigate to the test directories within the serialunix build and execute the unit and component test executables. This is done manually after setting up the environment variables.
```sh
$ cd $SERIALUNIXBASE/build/libnserial/unittest
$ ./nserialtest.exe
$ cd $SERIALUNIXBASE/build/libnserial/comptest
$ ./nserialcomptest.exe
```
--------------------------------
### Get Serial Port Descriptions
Source: https://github.com/jcurl/rjcp.dll.serialportstream/wiki/Getting-a-List-of-Serial-Ports-with-SerialPortStream
Retrieve a list of serial ports along with their descriptions. This method returns SerialPortStream.PortDescription objects. Ensure System.Diagnostics is imported.
```csharp
using System.Diagnostic;
foreach (SerialPortStream.PortDescription desc in SerialPortStream.GetPortDescriptions()) {
Trace.WriteLine("GetPortDescriptions: " + desc.Port + "; Description: " + desc.Description);
}
```
--------------------------------
### Package for NuGet Upload
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/BUILD.md
Builds and packages the project for upload to NuGet, including source symbols.
```cmd
PS1> dotnet build -c release .\code\SerialPortStream.csproj
PS1> dotnet pack -c release --include-source .\code\SerialPortStream.csproj
```
--------------------------------
### Run Unit Tests in Release Mode
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/BUILD.md
Executes unit tests for the Release configuration, logging results to a 'trx' file.
```cmd
PS1> dotnet test -c Release --logger "trx"
```
--------------------------------
### Instantiate SerialPortStream with Full Constructor Parameters
Source: https://github.com/jcurl/rjcp.dll.serialportstream/wiki/Overview-of-SerialPortStream-properties
Instantiate SerialPortStream with all basic serial communication parameters: port name, baud rate, data bits, parity, and stop bits.
```csharp
SerialPortStream s3 = new SerialPortStream("COM3", 115200, 8, Parity.None, StopBits.One);
```
--------------------------------
### Run BufferBytesTest Integration Test
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/test/README.md
Execute the BufferBytesTest command-line tool to send data over a serial port and monitor buffer status. Requires specifying the serial port, baud rate, and data length.
```cmd
BufferBytesTest --port COM1 --baud 115200 --length 163840
```
--------------------------------
### DataReceived Event Handling Example
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Handle the DataReceived event, which fires when data is available in the read buffer or an EOF character is detected. The event handler executes on a thread-pool thread and receives data as bytes, which can then be decoded.
```csharp
using RJCP.IO.Ports;
using System;
using System.Text;
using var serial = new SerialPortStream("COM3", 9600);
serial.Encoding = Encoding.ASCII;
serial.ReceivedBytesThreshold = 1;
serial.ReadTimeout = 500;
serial.DataReceived += (sender, e) =>
{
var s = (SerialPortStream)sender;
if (e.EventType == SerialData.Eof)
{
Console.WriteLine("[EOF character received]");
return;
}
// SerialData.Chars
byte[] buf = new byte[s.BytesToRead];
int n = s.Read(buf, 0, buf.Length);
Console.WriteLine($"Received {n} bytes: {Encoding.ASCII.GetString(buf, 0, n)}");
};
serial.Open();
Console.ReadLine(); // Keep alive
```
--------------------------------
### Instantiate SerialPortStream
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Demonstrates various ways to instantiate SerialPortStream, from default configuration to full parameter specification. For .NET 6+, an ILogger can be injected for diagnostics.
```csharp
using RJCP.IO.Ports;
// Default: no port assigned yet
var s1 = new SerialPortStream();
s1.PortName = "COM3";
s1.BaudRate = 9600;
// Port name only (baud/data/parity/stop loaded from current OS settings)
var s2 = new SerialPortStream("COM3");
// Port + baud
var s3 = new SerialPortStream("COM3", 115200);
// Full parameters: port, baud, data bits, parity, stop bits
var s4 = new SerialPortStream("COM3", 115200, 8, Parity.None, StopBits.One);
// .NET 6+ with injected ILogger
using Microsoft.Extensions.Logging;
ILogger logger = LoggerFactory.Create(b => b.AddConsole()).CreateLogger("Serial");
var s5 = new SerialPortStream(logger);
s5.PortName = "COM3";
```
--------------------------------
### DiscardInBuffer and DiscardOutBuffer Example
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Use DiscardInBuffer to clear unread bytes from the receive buffer and DiscardOutBuffer to clear unsent bytes from the transmit buffer. This is useful for dropping stale data before a protocol exchange or canceling pending outbound data.
```csharp
using RJCP.IO.Ports;
using var serial = new SerialPortStream("COM3", 9600);
serial.Open();
// Drop any stale data before starting a protocol exchange
serial.DiscardInBuffer();
Console.WriteLine($"Bytes to read after discard: {serial.BytesToRead}"); // 0
// Cancel pending outbound data
serial.DiscardOutBuffer();
Console.WriteLine($"Bytes to write after discard: {serial.BytesToWrite}"); // 0
```
--------------------------------
### Configure Logging via Singleton LogSource (.NET Core)
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Demonstrates setting a global ILoggerFactory for SerialPortStream instances when dependency injection is not used, suitable for migrating from .NET Framework. Call LogSource.SetLoggerFactory() once at application startup.
```csharp
using Microsoft.Extensions.Logging;
using RJCP.Diagnostics.Trace;
// Call once at application startup
ILoggerFactory factory = LoggerFactory.Create(builder =>
{
builder
.AddConsole()
.AddFilter("RJCP", LogLevel.Debug);
});
LogSource.SetLoggerFactory(factory);
// Now all SerialPortStream instances created normally will log via factory
using var serial = new RJCP.IO.Ports.SerialPortStream("COM3", 9600);
serial.Open();
serial.WriteLine("HELLO");
```
--------------------------------
### SerialPortStream Constructors
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Demonstrates various ways to instantiate the SerialPortStream class, from default initialization to specifying full port parameters and injecting an ILogger for diagnostics.
```APIDOC
## SerialPortStream Constructors
The `SerialPortStream` class inherits from `System.IO.Stream` and can be instantiated with zero arguments (deferred configuration), with a port name only, with port + baud, or with full port parameters. On .NET 6+, an `ILogger` can be injected for diagnostics.
```csharp
using RJCP.IO.Ports;
// Default: no port assigned yet
var s1 = new SerialPortStream();
s1.PortName = "COM3";
s1.BaudRate = 9600;
// Port name only (baud/data/parity/stop loaded from current OS settings)
var s2 = new SerialPortStream("COM3");
// Port + baud
var s3 = new SerialPortStream("COM3", 115200);
// Full parameters: port, baud, data bits, parity, stop bits
var s4 = new SerialPortStream("COM3", 115200, 8, Parity.None, StopBits.One);
// .NET 6+ with injected ILogger
using Microsoft.Extensions.Logging;
ILogger logger = LoggerFactory.Create(b => b.AddConsole()).CreateLogger("Serial");
var s5 = new SerialPortStream(logger);
s5.PortName = "COM3";
```
```
--------------------------------
### Build SerialPortStream on Linux
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/BUILD.md
Execute the dotnet build command from the solution directory to compile the SerialPortStream project. This command builds all projects in the solution, including the main library and test projects.
```bash
$ dotnet build
Microsoft (R) Build Engine version 16.9.0+57a23d249 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
SerialPortStream -> /home/jcurl/source/rjcp.dll.serialportstream/code/bin/Debug/net40/RJCP.SerialPortStream.dll
SerialPortStream -> /home/jcurl/source/rjcp.dll.serialportstream/code/bin/Debug/net45/RJCP.SerialPortStream.dll
SerialPortStreamTest -> /home/jcurl/source/rjcp.dll.serialportstream/test/SerialPortStreamTest/bin/Debug/net45/RJCP.SerialPortStreamTest.dll
DatastructuresTest -> /home/jcurl/source/rjcp.dll.serialportstream/test/DatastructuresTest/bin/Debug/net40/RJCP.DatastructuresTest.dll
SerialPortStreamTest -> /home/jcurl/source/rjcp.dll.serialportstream/test/SerialPortStreamTest/bin/Debug/net40/RJCP.SerialPortStreamTest.dll
DatastructuresTest -> /home/jcurl/source/rjcp.dll.serialportstream/test/DatastructuresTest/bin/Debug/net45/RJCP.DatastructuresTest.dll
```
--------------------------------
### Assigning the Virtual Factory
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/test/SerialPortStream.Virtual/README.md
This code snippet shows how to assign the VirtualSerialPortFactory to the global instance, enabling the use of virtual serial ports for testing.
```csharp
SerialPortFactory.Instance = new VirtualSerialPortFactory()
```
--------------------------------
### Build Docker Image for Ubuntu
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/docker/README.md
Builds the Docker image for a specific Ubuntu version. Set the CODENAME environment variable before running.
```sh
export CODENAME=focal
docker build --build-arg CODE_VERSION=${CODENAME} -t libnserial:${CODENAME} .
```
--------------------------------
### Find and Configure GTest for nserial Unit Tests
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/libnserial/unittest/CMakeLists.txt
This snippet finds the Google Test framework and configures the build to include it. It's essential for running the unit tests.
```cmake
find_package(GTest)
# Don't forget to enable_testing() in the root of your project
if(GTEST_FOUND)
find_package(Threads REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
set(SERIALUNIX_GTEST_SRCS
serialinit.cpp
serialopen.cpp
serialerror.cpp
serialmodem.cpp
main.cpp
configuration.cpp)
add_executable(nserialtest ${SERIALUNIX_GTEST_SRCS})
target_link_libraries(nserialtest nserial
${GTEST_MAIN_LIBRARIES} ${GTEST_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
add_test(NAME nserialtests COMMAND nserialtest)
endif(GTEST_FOUND)
```
--------------------------------
### Configure App.Config for SerialPortStream Tracing
Source: https://github.com/jcurl/rjcp.dll.serialportstream/wiki/Tracing
Add this XML configuration to your App.Config file to enable tracing for the IO.Ports.SerialPortStream source. Use a switchValue of 'Warning' or less for general debugging. Avoid tracing to the console as it can halt your application.
```xml
```
--------------------------------
### Initialize Singleton Logger with LoggerFactory
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/README.md
Configure and set a LoggerFactory for LogSource to obtain an ILogger instance. This is useful for .NET Core applications to manage logging configurations, especially when migrating from .NET Framework singletons. Ensure the factory is set once in your production code.
```csharp
using Microsoft.Extensions.Logging;
using RJCP.CodeQuality.NUnitExtensions.Trace;
using RJCP.Diagnostics.Trace;
internal static class GlobalLogger {
static GlobalLogger() {
ILoggerFactory factory = LoggerFactory.Create(builder => {
builder
.AddFilter("Microsoft", LogLevel.Warning)
.AddFilter("System", LogLevel.Warning)
.AddFilter("RJCP", LogLevel.Debug)
.AddNUnitLogger();
});
LogSource.SetLoggerFactory(factory);
}
public static void Initialize() {
/* Intentially empty. By calling this method, the static constructor
will be automatically called */
}
}
```
--------------------------------
### Build Debug Mode
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/BUILD.md
Builds the project in Debug mode. This does not generate a NuGet package.
```cmd
PS1> dotnet build
```
--------------------------------
### Implement APM Pattern with SerialPortStream
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
This code illustrates the use of the Asynchronous Programming Model (APM) with SerialPortStream, supporting legacy code that does not use async/await. It demonstrates BeginRead and BeginWrite operations.
```csharp
using RJCP.IO.Ports;
using System;
using System.Threading;
using var serial = new SerialPortStream("COM3", 9600);
serial.Open();
byte[] readBuf = new byte[64];
ManualResetEvent done = new(false);
IAsyncResult ar = serial.BeginRead(readBuf, 0, readBuf.Length, result =>
{
int n = serial.EndRead(result);
Console.WriteLine($"APM read: {n} bytes");
done.Set();
}, null);
// Write some data to trigger the read
byte[] tx = System.Text.Encoding.ASCII.GetBytes("Hello\n");
IAsyncResult war = serial.BeginWrite(tx, 0, tx.Length, result =>
{
serial.EndWrite(result);
Console.WriteLine("APM write complete");
}, null);
done.WaitOne(3000);
```
--------------------------------
### Instantiate SerialPortStream with Default Constructor
Source: https://github.com/jcurl/rjcp.dll.serialportstream/wiki/Overview-of-SerialPortStream-properties
Use the default constructor to create a SerialPortStream object with predefined default settings. Ensure PortName is set before opening.
```csharp
SerialPortStream s = new SerialPortStream();
```
--------------------------------
### Configure Logging with Dependency Injection (.NET Core)
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Shows how to inject an ILogger into SerialPortStream for structured logging in .NET 6+ applications. Configure the LoggerFactory to include console output and set the minimum log level.
```csharp
using Microsoft.Extensions.Logging;
using RJCP.IO.Ports;
ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
builder
.AddConsole()
.SetMinimumLevel(LogLevel.Debug)
.AddFilter("RJCP", LogLevel.Trace));
ILogger logger = loggerFactory.CreateLogger();
using var serial = new SerialPortStream(logger);
serial.PortName = "COM3";
serial.BaudRate = 115200;
serial.Open();
serial.Write(new byte[] { 0x01, 0x02 }, 0, 2);
```
--------------------------------
### Create Serial Port using SerialPortStreamFactory
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
This snippet demonstrates using SerialPortStreamFactory to create a platform-neutral SerialPortStream instance. It also shows how to replace the default factory for testing purposes with a custom virtual serial port factory.
```csharp
using RJCP.IO.Ports;
using System;
// Use the default factory
ISerialPortStreamFactory factory = SerialPortStreamFactory.Factory;
using SerialPortStream serial = factory.Create("COM3", 115200, 8, Parity.None, StopBits.One);
serial.ReadTimeout = 1000;
serial.Open();
serial.WriteLine("PING");
Console.WriteLine(serial.ReadLine());
// ─── For unit testing: inject a custom factory ─────────────────────────────
// SerialPortStreamFactory.Factory = new MyVirtualSerialFactory();
// ─── For dependency injection (test-friendly signature) ────────────────────
void Configure(ISerialPortStreamFactory fac)
{
using var s = fac.Create("COM3", 9600);
s.Open();
s.WriteLine("STATUS?");
}
Configure(SerialPortStreamFactory.Factory);
```
--------------------------------
### Instantiate SerialPortStream with Port Name and Baud Rate
Source: https://github.com/jcurl/rjcp.dll.serialportstream/wiki/Overview-of-SerialPortStream-properties
Instantiate SerialPortStream with the port name and baud rate. Other parameters will use default values.
```csharp
SerialPortStream s2 = new SerialPortStream("COM2", 115200);
```
--------------------------------
### Compile Software within Docker Container
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/docker/README.md
Compiles the software inside a Docker container. Ensure you are in the 'dll/serialunix' directory and have a 'build' directory. Mounts source and build directories, and uses a temporary filesystem for /tmp.
```sh
mkdir -p ../build
docker run -it --rm --read-only --cap-drop all \
-v ${PWD}:/source:ro \
-v ${PWD}/../build:/build:rw \
--tmpfs /tmp \
-u $(id -u ${USER}):$(id -g ${USER}) \
libnserial:${CODENAME}
```
--------------------------------
### Serial Configuration Properties
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Configures serial port parameters such as baud rate, data bits, parity, and flow control. Buffer sizes must be set before opening the port.
```APIDOC
## Serial Configuration Properties
Port parameters (`BaudRate`, `DataBits`, `StopBits`, `Parity`, `Handshake`, `DtrEnable`, `RtsEnable`, `BreakState`, etc.) can be set before or after `Open()`. Buffer sizes must be set before `Open()`.
```csharp
using RJCP.IO.Ports;
using var serial = new SerialPortStream();
serial.PortName = "COM3";
serial.BaudRate = 57600;
serial.DataBits = 8;
serial.StopBits = StopBits.One;
serial.Parity = Parity.Even;
serial.ParityReplace = 0x00; // Replace bad bytes with 0x00 (0 = disable)
serial.Handshake = Handshake.Rts; // RTS/CTS hardware flow control
// serial.Handshake = Handshake.XOn; // XON/XOFF software flow control
// serial.Handshake = Handshake.RtsXOn; // Both
// serial.Handshake = Handshake.Dtr; // DTR/DSR (uncommon)
serial.DtrEnable = true;
serial.RtsEnable = true;
serial.TxContinueOnXOff = false; // Pause TX when XOFF received
serial.DiscardNull = false; // Keep null bytes
// Buffer tuning (must be before Open)
serial.ReadBufferSize = 1024 * 1024; // 1 MB receive buffer
serial.WriteBufferSize = 128 * 1024; // 128 KB transmit buffer
serial.DriverInQueue = 4096; // Driver-level in-queue hint
serial.DriverOutQueue = 4096; // Driver-level out-queue hint
serial.ReceivedBytesThreshold = 1; // Fire DataReceived after 1+ bytes
serial.Open();
Console.WriteLine(serial.ToString());
// COM3:57600,8,E,1,to=off,xon=off,idsr=off,icts=hs,odtr=on,orts=hs
```
```
--------------------------------
### Define GTest Component Test Executable
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/libnserial/comptest/CMakeLists.txt
Defines the 'nserialcomptest' executable, linking it with the 'nserial' library and Google Test libraries. This builds the main component test suite.
```cmake
set(SERIALUNIXCOMP_GTEST_SRCS
SerialSendReceiveTest.cpp
SerialParityTest.cpp
SerialModemSignalsTest.cpp
SerialModemEvents.cpp
main.cpp
SerialConfiguration.cpp
Buffer.cpp
BuffDump.cpp
SerialReadWrite.cpp)
add_executable(nserialcomptest ${SERIALUNIXCOMP_GTEST_SRCS})
target_link_libraries(nserialcomptest nserial
${GTEST_MAIN_LIBRARIES} ${GTEST_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} rt)
```
--------------------------------
### Test Garbage Data on Serial Port Open
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/README.md
This command executes the kernelbug test to identify garbage data appearing at the beginning of a serial stream on certain Linux kernels and USB-SER drivers. Running the test twice can reveal the error.
```sh
$ kernelbug /dev/ttyUSB0 /dev/ttyUSB1
Offset: 4
Flushing...
Writing Complete...
Reading complete...
Comparison MATCH <---- PASS
Flushing...
Reading complete...
Complete...
$ kernelbug /dev/ttyUSB0 /dev/ttyUSB1
Offset: 108
Flushing...
Flush 2 bytes
Writing Complete...
Reading complete...
ERROR: Comparison mismatch <---- ERROR
Flushing...
Flush 510 bytes
Reading complete...
Complete...
```
--------------------------------
### Configure Handshake Settings for SerialPortStream
Source: https://context7.com/jcurl/rjcp.dll.serialportstream/llms.txt
Demonstrates setting the Handshake property on a SerialPortStream instance. Use Handshake flags to specify hardware or software flow control.
```csharp
var serial = new SerialPortStream("COM3", 115200);
serial.Handshake = Handshake.Rts; // RTS/CTS only
// serial.Handshake = Handshake.RtsXOn; // RTS/CTS + software XON/XOFF
```
--------------------------------
### App.config Test Port Settings
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/BUILD.md
Configuration settings for unit tests, specifying serial ports for Windows and Linux. Modify Win32SourcePort and Win32DestPort for actual hardware.
```xml
```
--------------------------------
### Instantiate SerialPortStream with Port Name
Source: https://github.com/jcurl/rjcp.dll.serialportstream/wiki/Overview-of-SerialPortStream-properties
Instantiate SerialPortStream by providing the port name. Other parameters will use default values.
```csharp
SerialPortStream s1 = new SerialPortStream("COM1");
```
--------------------------------
### Build Icount Executable
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/libnserial/comptest/CMakeLists.txt
Compiles the 'icount.c' file into a standalone executable. This utility might be used for counting or monitoring serial port events.
```cmake
add_executable(icount icount.c)
```
--------------------------------
### Find and Configure GTest
Source: https://github.com/jcurl/rjcp.dll.serialportstream/blob/master/dll/serialunix/libnserial/comptest/CMakeLists.txt
Locates the Google Test framework and includes its directories. This is necessary for building tests that use GTest.
```cmake
find_package(GTest)
```