84 lines
5.9 KiB
Markdown
84 lines
5.9 KiB
Markdown
---
|
|
source_files:
|
|
- Common/DTS.Common.IConnection/SerialConnection/SerialConnection.cs
|
|
generated_at: "2026-04-16T11:48:46.182914+00:00"
|
|
model: "zai-org/GLM-5-FP8"
|
|
schema_version: 1
|
|
sha256: "4992256eaf51da73"
|
|
---
|
|
|
|
# Documentation: DTS.Common.SerialConnection.SerialConnection
|
|
|
|
## 1. Purpose
|
|
The `SerialConnection` class provides a wrapper around `System.IO.Ports.SerialPort` to implement the `IConnection` interface. Its primary role is to abstract serial port communication behind an asynchronous, socket-like API (APM pattern). This allows serial devices to be handled uniformly within a system designed around generic connection interfaces, mimicking the behavior of network sockets for operations like connecting, sending, and receiving data.
|
|
|
|
## 2. Public Interface
|
|
|
|
**Class:** `SerialConnection` (implements `IConnection`)
|
|
|
|
**Properties:**
|
|
* `bool Connected { get; }`: Returns the connection state. **Note:** Currently hardcoded to return `false`.
|
|
* `bool IsSoftDisconnected { get; }`: Returns `true` if the unit is soft disconnected.
|
|
* `string ConnectString { get; }`: Returns the stored port name (`_PortName`).
|
|
* `System.Net.Sockets.SocketFlags Flags { get; set; }`: Gets or sets socket flags.
|
|
|
|
**Events:**
|
|
* `EventHandler OnDisconnected`: Event raised upon disconnection.
|
|
|
|
**Methods:**
|
|
* `void Create(string PortName)`: Instantiates the internal `SerialPort` object.
|
|
* `void Create(string connectString, string hostIPAddress)`: Overload that currently performs no operation.
|
|
* `void SoftConnect()`: Intended to connect the unit; currently empty.
|
|
* `void SoftDisconnect()`: Intended to disconnect the unit; currently empty.
|
|
* `string GetConnectionData()`: Returns an empty string.
|
|
* `double GetCurrentDownloadRate()`: Returns `0.0`.
|
|
* `double GetCurrentUploadRate()`: Returns `0.0`.
|
|
|
|
**Connection Lifecycle (APM Pattern):**
|
|
* `IAsyncResult BeginConnect(AsyncCallback cb, object state)`: Opens the serial port. Throws `Exception` if `Port` is null or `_PortName` is empty. Returns `null`.
|
|
* `void EndConnect(IAsyncResult ar)`: Validates `Port` exists. Throws `Exception` if null.
|
|
|
|
**Data Transfer (APM Pattern):**
|
|
* `IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`: Begins an asynchronous write to the serial port. Throws `Exception` if `Port` or `cb` is null.
|
|
* `int EndSend(IAsyncResult ar)`: Completes the asynchronous write. Returns `Port.BytesToWrite`.
|
|
* `Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend)`: Task-based async wrapper for `BeginSend`/`EndSend`.
|
|
* `IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`: Begins an asynchronous read from the serial port. Throws `Exception` if `Port` or `cb` is null.
|
|
* `int EndReceive(IAsyncResult ar)`: Completes the asynchronous read. Returns the number of bytes read.
|
|
|
|
**Server/Socket Mimicry Methods:**
|
|
* `IAsyncResult BeginAccept(AsyncCallback callback, Object state)`: Returns `null`. Throws if `Port` is null.
|
|
* `IConnection EndAccept(IAsyncResult asyncResult)`: Returns a new instance of `SerialConnection`. Throws if `Port` is null.
|
|
* `void Bind(int port)`: No-op. Throws if `Port` is null.
|
|
* `void Listen(int backlog)`: No-op. Throws if `Port` is null.
|
|
* `IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, Object state)`: Returns `null`. Throws if `Port` is null.
|
|
* `void EndDisconnect(IAsyncResult asyncResult)`: No-op. Throws if `Port` is null.
|
|
|
|
**IDisposable:**
|
|
* `void Dispose()`: Disposes the `SerialPort` and suppresses finalization.
|
|
|
|
## 3. Invariants
|
|
* **Null Checks:** Nearly all public methods (except `Create` overloads and disposal methods) throw a `System.Exception` if the protected `Port` field is null.
|
|
* **Callback Validation:** `BeginSend` and `BeginReceive` throw a `System.Exception` if the provided `AsyncCallback` is null.
|
|
* **Connection String:** `BeginConnect` throws a `System.Exception` if `_PortName` is null or empty.
|
|
* **Disposal:** Once `Dispose(bool disposing)` runs, the `Port` is closed and set to null; subsequent calls return immediately.
|
|
|
|
## 4. Dependencies
|
|
* **Dependencies (Imports):**
|
|
* `DTS.Common.Interface.Connection`: Defines the `IConnection` interface this class implements.
|
|
* `System.IO.Ports`: Provides the underlying `SerialPort` functionality.
|
|
* `System`: Basic system types, exceptions, and async patterns.
|
|
* `System.Threading.Tasks`: Used for `Task`-based async operations (`SendAsync`).
|
|
* **Dependents:** Unknown from source alone (consumers of `IConnection`).
|
|
|
|
## 5. Gotchas
|
|
* **Critical Bug in `Create(string PortName)`:** The method assigns `_PortName` *after* attempting to initialize `Port`.
|
|
```csharp
|
|
Port = new SerialPort(_PortName); // _PortName is likely null or stale here
|
|
_PortName = PortName; // Assigned too late
|
|
```
|
|
This results in the `SerialPort` being instantiated with an incorrect or empty port name, likely causing connection failures.
|
|
* **Hardcoded `Connected` Property:** The `Connected` property is hardcoded to return `false` and is never updated by `BeginConnect` or `EndConnect`. Code relying on this property to verify connectivity will fail.
|
|
* **APM Return Values:** `BeginConnect`, `BeginDisconnect`, and `BeginAccept` return `null` instead of a valid `IAsyncResult`. This may break callers expecting a valid state object from standard APM implementations.
|
|
* **`EndSend` Return Value:** `EndSend` returns `Port.BytesToWrite` (the number of bytes waiting in the send buffer), not the number of bytes successfully written (which is the standard behavior for socket `EndSend`).
|
|
* **Soft Disconnect Implementation:** `SoftConnect` and `SoftDisconnect` are empty methods. The `IsSoftDisconnected` property is initialized to `false` but is never set by any method in the class.
|
|
* **No-op Methods:** `Bind`, `Listen`, and `KeepAliveErrorReceived` perform no actions but throw exceptions if `Port` is null, making them effectively validation checks with no side effects. |