Oakrey.PSAP
2.0.2
dotnet add package Oakrey.PSAP --version 2.0.2
NuGet\Install-Package Oakrey.PSAP -Version 2.0.2
<PackageReference Include="Oakrey.PSAP" Version="2.0.2" />
<PackageVersion Include="Oakrey.PSAP" Version="2.0.2" />
<PackageReference Include="Oakrey.PSAP" />
paket add Oakrey.PSAP --version 2.0.2
#r "nuget: Oakrey.PSAP, 2.0.2"
#:package Oakrey.PSAP@2.0.2
#addin nuget:?package=Oakrey.PSAP&version=2.0.2
#tool nuget:?package=Oakrey.PSAP&version=2.0.2
Oakrey.PSAP
.NET managed wrapper for the eCall PSAP (Public Safety Answering Point) protocol.
Exposes native Win32/x64 eCall modem DLL functions as reactive IObservable streams
and provides PCM audio frame processing for automotive and telematics applications.
Main features
- Reactive API (
System.Reactive) for PSAP events, MSD reception, log output, and abort notifications - Dual-architecture native interop: automatic selection of
ECallModem_Win32.dll(x86) orECallModem_x64.dll(x64) at runtime - PCM audio frame processing — push 160-sample
short[]frames from the audio pipeline - Protocol control:
SendStart,Reset, and HLACK acknowledgement - Full
PSAPEventenumeration covering the complete eCall modem state machine
Requirements
- .NET 10 or higher
- Windows (x86 or x64) — native DLLs are Windows-only
ECallModem_Win32.dllandECallModem_x64.dllmust be present next to the consuming assembly (included in the NuGet package viaPackageCopyToOutput)
Installation
.NET CLI
dotnet add package Oakrey.PSAP
Package Manager Console
Install-Package Oakrey.PSAP
NuGet Package Manager (Visual Studio)
Search for Oakrey.PSAP under Tools > NuGet Package Manager > Manage NuGet Packages for Solution and click Install.
Architecture
PSAPWrapper
|-- IObservable<PSAPEvent> PsapEvent
|-- IObservable<byte[]> MsdReceived
|-- IObservable<string> Log
|-- IObservable<string> Abort
|
|-- static ProcessFrame(ref short[] frame) // feed 160-sample PCM frames
|-- static SendStart() // initiate PSAP sequence
|-- static Reset() // reset modem state
|
'-- P/Invoke partials -> ECallModem_Win32.dll / ECallModem_x64.dll
PSAPWrapper registers managed delegates with the native modem library on construction.
All callbacks are forwarded to Subject<T> instances and exposed as IObservable<T>.
Protocol flow
sequenceDiagram
participant App
participant PSAPWrapper
participant NativeDLL as ECallModem DLL
App->>PSAPWrapper: new PSAPWrapper()
PSAPWrapper->>NativeDLL: SetLog / SetAbort / SetPsapMsd / SetPsapEvent
App->>PSAPWrapper: Subscribe to PsapEvent, MsdReceived, Log, Abort
App->>PSAPWrapper: SendStart()
PSAPWrapper->>NativeDLL: PsapSendStart
loop Audio pipeline (8 kHz, 20 ms frames)
App->>PSAPWrapper: ProcessFrame(ref frame)
PSAPWrapper->>NativeDLL: PsapProcess(pcm)
end
NativeDLL-->>PSAPWrapper: PsapEvent callback (SENDINGSTART, MSDSYNC, ...)
PSAPWrapper-->>App: PsapEvent.OnNext(PSAPEvent.MSDSYNC)
NativeDLL-->>PSAPWrapper: MSD callback (byte[], length)
PSAPWrapper-->>App: MsdReceived.OnNext(msdBytes)
App->>PSAPWrapper: Reset()
PSAPWrapper->>NativeDLL: PsapReset
Usage
Basic setup
using Oakrey.PSAP;
PSAPWrapper psap = new PSAPWrapper();
psap.PsapEvent.Subscribe(e => Console.WriteLine($"Event: {e}"));
psap.MsdReceived.Subscribe(msd => Console.WriteLine($"MSD received: {msd.Length} bytes"));
psap.Log.Subscribe(msg => Console.WriteLine($"[LOG] {msg}"));
psap.Abort.Subscribe(msg => Console.WriteLine($"[ABORT] {msg}"));
PSAPWrapper.SendStart();
Audio frame loop
Feed 160-sample PCM frames (8 kHz, 16-bit, 20 ms) from your audio source:
short[] frame = new short[160];
// Fill frame from audio device, then:
PSAPWrapper.ProcessFrame(ref frame);
PSAPEvent values
| Value | Description |
|---|---|
SENDINGSTART |
Vehicle modem started sending |
SENDINGRESTART |
Sending restarted |
SENDINGLLACK |
Low-layer acknowledgement sent |
SENDINGHLACK |
High-layer acknowledgement sent |
CONTROLSYNC |
Control synchronisation achieved |
CONTROLLOCK |
Control channel locked |
MSDSYNC |
MSD synchronisation achieved |
MSDRECEIVED |
Full MSD received |
IDLEPOSTRESET |
Idle after reset |
IDLEPOSTSTART |
Idle after start |
IDLEPOSTLLACK |
Idle after LLACK |
IDLEPOSTHLACK |
Idle after HLACK |
TIMEOUT |
Protocol timeout |
Development notes
- The two native DLLs are shipped with the NuGet package and copied to the output directory automatically.
PSAPWrappermust remain alive (not garbage-collected) for the lifetime of the native callbacks. Disposing the subjects or letting the wrapper go out of scope while the native modem is active will cause a native crash.ProcessFrameandReset/SendStartarestaticand can be called without an instance; the instance is only needed to hold the callback delegates alive.- The HLACK acknowledgement is sent automatically inside
PsapMsdCallbackwith a fixed value of0. Verify whether your use case requires a different HLACK payload.
License
MIT — Copyright (c) Oakrey 2016-present
Project information
- Author: Oakrey
- Repository: https://dev.azure.com/oakrey/OpenPackages/_git/Protocols
- Project URL: http://www.oakrey.cz/opkg_protocols_dbc
Contributing
Contributions are welcome! Feel free to open issues or submit pull requests to improve the package.
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
- System.Reactive (>= 7.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.