Oakrey.PSAP 2.0.2

dotnet add package Oakrey.PSAP --version 2.0.2
                    
NuGet\Install-Package Oakrey.PSAP -Version 2.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Oakrey.PSAP" Version="2.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Oakrey.PSAP" Version="2.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Oakrey.PSAP" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Oakrey.PSAP --version 2.0.2
                    
#r "nuget: Oakrey.PSAP, 2.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Oakrey.PSAP@2.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Oakrey.PSAP&version=2.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Oakrey.PSAP&version=2.0.2
                    
Install as a Cake Tool

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) or ECallModem_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 PSAPEvent enumeration covering the complete eCall modem state machine

Requirements

  • .NET 10 or higher
  • Windows (x86 or x64) — native DLLs are Windows-only
  • ECallModem_Win32.dll and ECallModem_x64.dll must be present next to the consuming assembly (included in the NuGet package via PackageCopyToOutput)

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.
  • PSAPWrapper must 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.
  • ProcessFrame and Reset/SendStart are static and can be called without an instance; the instance is only needed to hold the callback delegates alive.
  • The HLACK acknowledgement is sent automatically inside PsapMsdCallback with a fixed value of 0. Verify whether your use case requires a different HLACK payload.

License

MIT — Copyright (c) Oakrey 2016-present

Project information

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.2 151 8/3/2026
2.0.1 152 5/15/2026
2.0.0 153 2/2/2026
1.1.0 303 6/18/2025
1.0.0 232 6/18/2025