Oakrey.Capsule.Base
2.0.2
dotnet add package Oakrey.Capsule.Base --version 2.0.2
NuGet\Install-Package Oakrey.Capsule.Base -Version 2.0.2
<PackageReference Include="Oakrey.Capsule.Base" Version="2.0.2" />
<PackageVersion Include="Oakrey.Capsule.Base" Version="2.0.2" />
<PackageReference Include="Oakrey.Capsule.Base" />
paket add Oakrey.Capsule.Base --version 2.0.2
#r "nuget: Oakrey.Capsule.Base, 2.0.2"
#:package Oakrey.Capsule.Base@2.0.2
#addin nuget:?package=Oakrey.Capsule.Base&version=2.0.2
#tool nuget:?package=Oakrey.Capsule.Base&version=2.0.2
Oakrey.Capsule.Base
Overview
Oakrey.Capsule.Base is a .NET 10 base library for building binary protocol capsules. A capsule is a self-describing binary frame that carries a fixed header (hardware ID, protocol ID, timestamp, version) and a typed payload. The library provides span-based serialization, a protocol-ID-keyed deserialization registry, and a built-in LoggingCapsule. It is designed as the foundation for domain-specific capsule packages such as Oakrey.Capsule.Can and Oakrey.Capsule.Lin.
Main Features
Binary Header
CapsuleHeadcarriesHardwareId,ProtocolId,Timestamp(ticks), andVersion.- Header is parsed from a
ReadOnlySpan<byte>at fixed offsets; no heap allocation for the parse step.
Serialization and Deserialization
Serialize()writes the header and payload into abyte[]viaBinaryWriter.CapsuleBase.Deserialize(ReadOnlySpan<byte>)reads the protocol ID from the frame and dispatches to the registered capsule type.- Head check code (
"ch") is validated on every deserialization call.
Deserialization Registry
- Call
AddToCache()on a capsule instance to register its type against its protocol ID. Deserializeuses the registry to instantiate the correct concrete type via itsReadOnlySpan<byte>constructor.
Logging Capsule
LoggingCapsuleis a ready-to-use capsule for transporting log messages with aLogCodeclassification.
Helper Extensions
SpanHelper� readushort,uint,long, and UTF-8 strings from aReadOnlySpan<byte>at an offset.BinaryWriterHelper� write UTF-8 strings viaBinaryWriter.
Architecture
classDiagram
direction TB
class ICapsule {
<<interface>>
+Id: ushort
+Name: string
+Head: CapsuleHead
+ContentToString: string
+OneLineInfo: string
+Serialize() byte[]
+AddToCache() bool
}
class CapsuleBase {
<<abstract>>
+Deserialize(payload) ICapsule$
#WritePayload(writer)
}
class CapsuleHead {
+HardwareId: ushort
+ProtocolId: ushort
+Timestamp: long
+Version: byte
}
class LoggingCapsule {
+Code: LogCode
+Message: string
+Id: ushort = 0x0000
}
ICapsule <|.. CapsuleBase
CapsuleBase --> CapsuleHead
CapsuleBase <|-- LoggingCapsule
Binary Frame Layout
| Offset (bytes) | Length | Field |
|---|---|---|
| 0 | 2 | Check code ("ch" in UTF-8) |
| 2 | 2 | HardwareId |
| 4 | 2 | ProtocolId |
| 6 | 8 | Timestamp (long, ticks) |
| 16 | 1 | Version |
| 17+ | variable | Payload (defined by each capsule) |
Requirements
- .NET 10 or higher
- No external NuGet dependencies
Installation
.NET CLI
dotnet add package Oakrey.Capsule.Base
Package Manager Console
Install-Package Oakrey.Capsule.Base
NuGet Package Manager
- Open your project in Visual Studio.
- Navigate to Tools > NuGet Package Manager > Manage NuGet Packages for Solution.
- Search for
Oakrey.Capsule.Baseand click Install.
Usage
1. Define a custom capsule
Inherit from CapsuleBase, declare a unique Id and a ReadOnlySpan<byte> constructor for deserialization:
public class TemperatureCapsule : CapsuleBase
{
public override ushort Id => 0x0010;
public override byte Version => 1;
public float Temperature { get; private set; }
private const int temperatureOffset = payloadOffset;
// For creating a new capsule to send
public TemperatureCapsule(float temperature, ushort hwId) : base(hwId, 1)
{
Temperature = temperature;
}
// Required for deserialization dispatch
public TemperatureCapsule(ReadOnlySpan<byte> payload) : base(payload)
{
Temperature = BitConverter.ToSingle(payload.Slice(temperatureOffset, 4));
}
protected override void WritePayload(BinaryWriter writer)
{
writer.Write(Temperature);
}
public override string ContentToString => $"Temperature: {Temperature} C";
public override string OneLineInfo => $"Temp: {Temperature:F1} C";
}
2. Register capsule types
Register each capsule type once at startup, before any deserialization calls:
new TemperatureCapsule(0, hwId: 0).AddToCache();
new LoggingCapsule().AddToCache();
3. Serialize
TemperatureCapsule capsule = new TemperatureCapsule(23.5f, hwId: 0x0001);
byte[] frame = capsule.Serialize();
4. Deserialize
ICapsule received = CapsuleBase.Deserialize(frame);
if (received is TemperatureCapsule temp)
{
Console.WriteLine(temp.Temperature);
}
5. LoggingCapsule
LoggingCapsule log = new LoggingCapsule("Device started", LogCode.StartedSuccessfully, hwId: 0x0001);
byte[] frame = log.Serialize();
Development Notes
- The deserialization registry (
cachedCapsules) is a staticDictionary<ushort, ICapsule>onCapsuleBase. It is process-global and not thread-safe for concurrentAddToCachecalls during initialization � register all types before processing data. LogCodeis auintenum. Add application-specific codes by extending it in your own assembly.- The check code
"ch"is validated on deserialization; frames with a wrong prefix throw an exception before any capsule lookup.
Project Information
| Field | Value |
|---|---|
| Author | Oakrey |
| License | MIT |
| NuGet | Oakrey.Capsule.Base |
| Repository | Azure DevOps |
License
This project is licensed under the MIT License. See the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Oakrey.Capsule.Base:
| Package | Downloads |
|---|---|
|
Oakrey.Capsule.Metadata
Capsule.Metadata encodes strongly-typed key-value metadata records into the Oakrey Capsule binary framing protocol (capsule ID 0xFFFF). Each record carries a key, a DataType (String, Boolean, Byte, Short, Long, Int, Float, Double), an optional Unit, and a typed value. Up to 255 records can be batched in a single MetaCapsule. Suitable for IoT, telemetry, and data-logging scenarios. |
|
|
Oakrey.Capsule.Can
Capsule.Can provides CAN and CAN-FD message types, multi-message batching, channel settings, and channel status capsules encoded in the Oakrey Capsule binary framing protocol. Suitable for automotive, industrial, and IoT data-logging and communication scenarios. |
|
|
Oakrey.Capsule.Lin
Capsule.Lin provides LIN bus message types, multi-message batching, channel settings, and channel status capsules encoded in the Oakrey Capsule binary framing protocol. Supports Observer, Slave, Master, and Scheduler channel modes. Suitable for automotive and industrial data-logging scenarios. |
GitHub repositories
This package is not used by any popular GitHub repositories.