.NET NORM Extension (#85)
* .NET Extension Design (#5)
* Designed .NET classes from Java
Co-authored-by: Sergiy <sergiy.yermak.ctr@us.navy.mil>
* Added NormApi static class
* Started on api uml
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>
* Add static methods to api uml
* add static method to normapi uml
* Add enums
* Changes
* Overload methods with defaults
* type marshalling
* change handles to in nuint
* marshall more handles
* Removed in/ref and reformatted.
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
* Removed duplicate enums
* Removed NormEvent from NormApi
* Fixed typo
* design NormInstance methods
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
* Fixed CreateInstance method
* Changed handles to long
* Change id types to long
* Remove condition checks that do nothing
* Removed UserData functions
* Removed NormAlloc() and NormFree()
* Cleaned up some API methods
* Fix misspelling
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>
* Design NormSession methods
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>
* Added missing comma
* Uml for enqueue
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
* Updated design based on enqueue test
* Updated EnqueueFile sequence diagram
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>
* Moved sequence diagrams
* Added constants to NormApi
* Removed method level sequence diagrams
---------
Co-authored-by: Sergiy <sergiy.yermak.ctr@us.navy.mil>
Co-authored-by: syermak <syerm001@odu.edu>
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>
Co-authored-by: Sergiy <47069243+SergiyYermak@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfreeman3@gmail.com>
* .NET Extension Design Implementation (#10)
* changes
* Removed GetsNextEvent test
* Implemented GetNextEvent
* Fixed NormStream design
* Fixed HasNextEvent design
* Added NormGetNextEvent overload
* Implemented HasNextEvent
* Updated design
* Added Kernel32 to design
* Modified to use .NET EventWaitHandle instead of kernel32 P/Invoke
* Modified to only copy norm.dll on Windows
* Added copy for non Windows
* add start and stop receiver
* add receiver
* Modified non-Windows to use Socket for HasNextEvent
* Deleted NormFileTests since they break the other tests
* Fixed ReceiverReceives test
* Updated ReceiverReceives test name
* Modified ReceivesFile to get all events instead of adding to array
* Cleaned up NormInstance formatting
* Refactored tests
* Updated NormFile
* Implemented send stream
* Implemented receive stream
* Implemented NormFile Name
* Updated ReceivesFile to use events
* data enqueue
* Fixed merge
* Fixed ReceivesData test
* Modified data test to compare collections without order
* stop instance working
* enqueues data
* Reverted upgrade to .NET 7
* Restartinstance is working
* Modified NormData to read bytes instead of as string
* Removed using statements in NormData
* Updated design
* Updated design
* Switched to nint
* Switched design to nint
* unfinished test for suspendinstance
* working suspend instance
* added resume function to instance
* Updated session send and receive data tests
* Removed launch settings
* session configuration functions
* Modified to use random port due to intermittent failed tests due to session conflict
* Modified to randomize text content
* Implemented NormNode Address
* Updated design for NormNode
* Implemented NormNode Grtt
* Implemented NormNode Id
* implement session configuration functions
* instance
* missing return types
* add missing handle param
* normNode
* Implemented RequeueObject
* Implemented SetWatermark and AckingNode
* Implemented CancelWatermark
* Implemented ResetWatermark
* Implemented SendCommand
* Implemented CancelCommand
* Implemented DebugLevel. Removed DebugPipe
* Updated SetTxPort
* Updated SetRxPortReuse
* Implemented SetEcnSupport
* Added test for RxLoss
* Implemented ReportInterval
* Refactored session calculated properties
* Updated enqueue methods
* Updated StreamOpen design
* Fixed SetWatermark overload
* Implemented GetAckingStatus
* Removed SendCommand overload
* Removed SetSilentReceiver overload
* Implemented NormEvent ToString
* Implemented NormFile Rename
* Implemented SetUnicastNack
* Added ReceivesCommand test
* Implemented SetNackingMode
* Implemented SetRepairBoundary
* Added Fact to SetsRepairBoundary test
* Implemented SetRxRobustFactor
* Implemented NormNode Command
* Implemented FreeBuffers
* Implemented Retain and Release
* Fix using namespaces
* test get object type
* NormObject get size
* NormObject setNackingMode
* NormObject get bytes pending
* NormObjet cancel
* NormObject retain
* NormObject release
* NormObject get sender
* NormObject get hashcode
* normObject equals
* Implemented NormObject Equals
* Removed redundant cast
* Removed unused using directive
* Removed static using
* Added NormApi to global Usings
* Added Enums to global usings
* Cleaned up NormObject Equals
* Cleaned up NormObject GetHashCode() test
* Cleaned up warning
* normStream has vacancy
* normStream read offset
* normStream seek msg start
* NormEventListener interface
* normStream set push enable
* normStream set auto flush
* Simplified NormApi usage
* Updated design of NormStream
* public interface
* Fixed INormEventListener
* fixing name space
* commit initializing inputstream
* Added StreamBreakException
* Fixed formatting
* Fixed formatting
* Fixed formatting
* Initial implementation of NormOutputStream
* Cleaned up NormObject Equals
* NormInputStream class
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
* normStream data offset
* move offset length arithmetic into write method
* building normInputstream
* all method implemented
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
* NormStreamRead
* Fixed build error
* Completed ReceivesStreamWithOffset test
* Added retries to GetsCommand test
* Updated type for NormStreamRead
* Simplified NormStream Read
* Simplified NormStream Write
* Added dataOffset to DataEnqueue
* Fixed DataEnqueue overload
* Added infoOffset to FileEnqueue
* Added infoOffset to StreamOpen
* Updated design
* Removed extra overload of FileEnqueue
* Removed DataEnqueue overloads
* Removed extra overload from StreamOpen
* Added HasNextEvent overload
* Implemented OpenDebugPipe
* add thread locking
* locking for properties
* Not supported exceptions
* Implementing sychronize
* fixing inputstream
* adding sychronize message
* Reorganized NormApi and updated design
* Modified to skip GetsCommand test on IO exception
* WIP: 537b706 adding sychronize message
* adding message to expections
* Fixed test file cleanup
* Added locking to NormSession methods that use static field
* Changed StartsSender to skippablefact
* Changed to SetsNackingMode to skippable fact
* Converted tests to skippable
* Converted more tests to skippable
* Converted all tests that start sender to skippable
* Updated README about skipped tests
* documentation
* 2 doc
* Cleaned up input and output stream classes
* Cleaned up NormApi
* Updated NormOutputStream Write
* Added document comments to NormApi
* Added comments to NormApi
* Removed unnecessary usings
* Added comments to NormApi
* set up the rest of doc
* api documentation
* fix typo
* fix spacing
* Doc for instance need clean up
* clean up
* document norm session
* NormStream documentation
* commit for node
* NormObject docs
* Updated NormApi comments
* Cleaned up NormInstance comments
* Cleaned up NormNode comments
* Cleaned up NormObject comments
* Cleaned up NormSession comments
* Cleaned up NormStream comments
* Cleaned up NormObject comments
* Adding commits
* Update get commit
* clean up on data and event
* Norm Data change
* clean up normfile docs
* clean up normstream
* clean up api docs
* Fixed data
* space approved
* Cleaned up NormData comment
* documentation clean up
* Update the ReadMe
* Cleaned up comments
* Added comments to NormAckingStatus
* Added comments to NormEventType
* Added comments to NormFecType
* Added comments to NormNackingMode
* Added comments to NormObjectType
* Added comments to NormProbingMode
* Added comments to NormRepairBoundary
* Added comments to NormFlushMode
* Added comments to NormSyncPolicy
* Cleaned up comments. Fixed default for StartSender
* Added comments to constants
* Moved constants to relevant classes
* Updated design
* Removed NormDataDetachData since it is not referenced
* Updated design
* Updated input and output stream design
* Updated packaging README
* Removed language version since redundant
* Cleaned up project file
* Updated to package from the dotnet directory (test project is set to not pack)
* Added version to project
---------
Co-authored-by: syermak <syerm001@odu.edu>
Co-authored-by: Sylvester Freeman III <Slyfreeman3@gmail.com>
Co-authored-by: Sergiy <47069243+SergiyYermak@users.noreply.github.com>
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
* NormSession typos in comments (#12)
* Fixed default function comments in NormSession
* Fixed typos in NormSession
* Fixed default function comments
* Feature/9 net norm extension target architecture packages (#13)
* Added Win64 project and release configuration
* Added project reference to Win64 project
* Added Win32 project. Moved norm build actions to scripts
* Added linux .NET extension project
* Modified linux project to copy to output directory
* Fixed linux pack script
* Changed Linux project to copy always
* Changed Linux project package path
* Moved Windows libraries to runtimes path
* Renamed runtime specific projects
* Codespace Configurations (#15)
* Created devcontainer.json
* .NET norm extension GitHub actions (#16)
* Added .NET action
* Update dotnet-publish.yml to use source branch (#18)
* .NET norm package publish (#19)
* Added steps to copy package and check workspace
* Changed trigger for testing
* Removed if statement
* Updated dotnet-publish.yml to copy to $GITHUB_OUTPUT
* Changed from variable to path
* Removed copy command
* Modified to check runner directory
* Added step to publish package
* Added package write permission
* Added job to publish win-x64
* Fixed package win-x64 step
* Added job to publish win-x86
* Added skip-duplicate to publish commands
* Added publish job
* Changed to . for linux find
* Added workflow trigger
* Added branches filter
* Publish test results (#21)
* Added step to publish test results
* Changed upload step to use wildcard
* Added quotes
* Changed directory to relative path
* Fixed upload step
* Added step to publish test results
* Added permissions
* Dev Container extensions (#23)
* Added extensions
* Cut down on extensions
* Added extension
* Removed pull requests extension
* Added workspace recommendation
* Added powershell feature
* Fixed powershell version
* Updated powershell version and added extension
* Updated to latest powershell
* Dev Container performance (#25)
* Fixed devcontainer format
* Added dotnet-linux-x64 devcontainer
* Changed devcontainer image to python
* Pinned OS version
* Updated devcontainer base image
* Reverted changes to devcontainer
* Moved linux devcontainer file
* Updated dotnet-publish to use subfolder
* Revert "Dev Container performance (#25)" (#27)
This reverts commit 2be146ceed.
* Update action versions for dotnet-publish.yml
* Update action versions for dotnet.yml
* Fixed ReceivesData test to use received events for actual data
* NormData Refactor (#30)
* Switched NormData Data property to a method
* Corrected NormData summary comment
* Updated NormData GetData to use Marshal.Copy
* Fixed warnings
* Updated NormData design
* NormDataEnqueue Refactor (#31)
* Switched NormDataEnqueue to use IntPtr
* Updated NormApi design
* Updated GetSession to use lock
* Updated GetSession to TryGetValue
* DataEnqueue Refactor (#33)
* Refactored DataEnqueue to use pointer arithmetic
* NormDataEnqueue Refactor (#34)
* Updated to use SafeBuffer
* Added ByteBuffer and DirectByteBuffer
* Added pointer overload to DataEnqueue
* Updated FileEnqueue() to use pointer arithmetic
* Updated NormStream to use pointer arithmetic
* Updated NormSendCommand to nint
* Updated NormNodeGetCommand to nint
* Updated NormNodeGetAddress to use nint for buffer
* Updated NormStreamRead to use nint for buffer
* Updated NormObjectGetInfo to use nint for buffer
* Updated NormFileGetName nameBuffer to nint
* Updated NormFile.Name to use PtrToStringAnsi
* Updated NormFile.Name to use stackalloc (#37)
* Updated NormNode.Address to use stackalloc and create IPAddress from bytes
* NormObject Refactor
* Updated NormObjectGetInfo to use byte array
* Updated design
* NormStream Refactor
* Updated NormStream Write to use fixed statement
* Updated NormStream Read to use fixed statement
* Updated design
* NormNode Refactor
* Updated NormNodeGetAddress to use byte* to avoid casting
* Updated NormNode GetCommand to use fixed statement
* Updated design
* NormFile Refactor
* Updated NormFileGetName to use sbyte* to avoid casting
* Updated design
* Added workflow_dispatch to workflows
---------
Co-authored-by: Sergiy <sergiy.yermak.ctr@us.navy.mil>
Co-authored-by: syermak <syerm001@odu.edu>
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>
Co-authored-by: Sergiy <47069243+SergiyYermak@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfreeman3@gmail.com>
norm-ccd
parent
0c2e151a77
commit
4fd768f9cc
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"image": "mcr.microsoft.com/devcontainers/cpp:1.0.0-buster",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/python:1": {
|
||||
"version": "3.11"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/dotnet:1": {
|
||||
"version": "6"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/java:1": {
|
||||
"version": "17",
|
||||
"installAnt": true,
|
||||
"antVersion": "1.10.12"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {
|
||||
"version": "20.10"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/powershell:1": {
|
||||
"version": "7.3"
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"DavidAnson.vscode-markdownlint",
|
||||
"eamodio.gitlens",
|
||||
"github.vscode-github-actions",
|
||||
"GitHub.codespaces",
|
||||
"jebbs.plantuml",
|
||||
"ms-python.isort",
|
||||
"ms-vscode-remote.remote-containers",
|
||||
"ms-vscode.cpptools-themes",
|
||||
"ms-vscode.PowerShell",
|
||||
"tomoki1207.pdf",
|
||||
"yzhang.markdown-all-in-one"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
*.sh text eol=lf
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
name: ".NET Publish"
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ['.NET']
|
||||
types:
|
||||
- completed
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/dotnet
|
||||
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
- name: Package .NET
|
||||
run: dotnet pack . -c Release
|
||||
- name: Publish .NET
|
||||
run: |
|
||||
package=$(find . -type f -name "*.nupkg")
|
||||
dotnet nuget push "$package" --skip-duplicate
|
||||
|
||||
publish-linux-x64:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Package .NET
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
runCmd: |
|
||||
cd ./src/dotnet
|
||||
chmod 755 *.sh
|
||||
./pack-linux-x64.sh
|
||||
- name: Set up .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
- name: Publish .NET
|
||||
run: |
|
||||
package=$(find . -type f -name "*linux-x64*.nupkg")
|
||||
dotnet nuget push "$package" --skip-duplicate
|
||||
|
||||
publish-win-x64:
|
||||
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
packages: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/dotnet
|
||||
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5.1.0
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
- name: Package .NET
|
||||
run: .\pack-win-x64.bat
|
||||
- name: Publish .NET
|
||||
run: |
|
||||
$package=Get-ChildItem -Path .\ -Filter *win-x64*.nupkg -Recurse -File | ForEach-Object { $_.FullName }
|
||||
dotnet nuget push "$package" --skip-duplicate
|
||||
|
||||
publish-win-x86:
|
||||
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
packages: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/dotnet
|
||||
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5.1.0
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
- name: Package .NET
|
||||
run: .\pack-win-x86.bat
|
||||
- name: Publish .NET
|
||||
run: |
|
||||
$package=Get-ChildItem -Path .\ -Filter *win-x86*.nupkg -Recurse -File | ForEach-Object { $_.FullName }
|
||||
dotnet nuget push "$package" --skip-duplicate
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
name: .NET
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
checks: write
|
||||
pull-requests: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/dotnet
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5.1.0
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Build NORM
|
||||
run: ./waf
|
||||
working-directory: .
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore /property:Configuration=Release
|
||||
- name: Build
|
||||
run: dotnet build --no-restore --configuration Release
|
||||
- name: Test
|
||||
run: dotnet test --no-build --verbosity normal --configuration Release --logger trx --results-directory TestResults
|
||||
- name: Upload test results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: dotnet-results
|
||||
path: ./src/dotnet/TestResults
|
||||
if: ${{ always() }}
|
||||
- name: Publish test results
|
||||
uses: EnricoMi/publish-unit-test-result-action@v2
|
||||
with:
|
||||
files: ./src/dotnet/TestResults/*.trx
|
||||
if: ${{ always() }}
|
||||
|
|
@ -18,9 +18,16 @@ norp/makefiles/norp
|
|||
*.o
|
||||
*.a
|
||||
|
||||
# build java files
|
||||
*.class
|
||||
|
||||
#build android files
|
||||
android/.gradle
|
||||
|
||||
# waf cruft
|
||||
.waf*
|
||||
.lock-waf*
|
||||
waf*/*
|
||||
|
||||
# OS generated files #
|
||||
.DS_Store
|
||||
|
|
@ -30,3 +37,275 @@ norp/makefiles/norp
|
|||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
*.sqlite
|
||||
*.sqlite-shm
|
||||
*.sqlite-wal
|
||||
|
||||
# Nuget files
|
||||
DeploymentSettings.props
|
||||
Directory.Build.props
|
||||
Directory.Build.targets
|
||||
Packages.props
|
||||
|
||||
#Local Log Files
|
||||
log*.txt
|
||||
|
||||
.NET Extension Library Files
|
||||
/src/dotnet/lib
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"github.vscode-pull-request-github"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
.NET extension for NORM
|
||||
==========================
|
||||
|
||||
By:
|
||||
Jeff Muller <jeffrey.muller3.ctr@us.navy.mil>
|
||||
Sylvester Freeman <sylvester.freeman18.civ@us.navy.mil>
|
||||
Sergiy Yermak <sergiy.yermak.ctr@us.navy.mil>
|
||||
|
||||
The .NET extension for NORM provides a .NET wrapper for the NORM C API.
|
||||
|
||||
For documentation about the main NORM API calls, refer to the NORM Developers
|
||||
guide in the regular NORM distribution.
|
||||
|
||||
The .NET extension can be built using the .NET CLI.
|
||||
|
||||
------------
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The .NET extension for NORM requires at least .NET SDK 6.0.
|
||||
|
||||
The NORM library should be built prior to building the .NET extension since it is invoked by the .NET extension.
|
||||
|
||||
------------
|
||||
Building
|
||||
------------
|
||||
|
||||
To build the .NET extension for NORM, execute the .NET CLI command in the src/dotnet directory:
|
||||
|
||||
```
|
||||
dotnet build .
|
||||
```
|
||||
|
||||
------------
|
||||
Testing
|
||||
------------
|
||||
|
||||
To test the .NET extension for NORM, execute the .NET CLI command in the src/dotnet directory:
|
||||
|
||||
```
|
||||
dotnet test .
|
||||
```
|
||||
|
||||
The test command results should show that all tests have passed.
|
||||
Some tests might be skipped due to IO exception.
|
||||
|
||||
------------
|
||||
Packaging
|
||||
------------
|
||||
To package the .NET extension for NORM, execute the .NET CLI command in the src/dotnet directory:
|
||||
|
||||
```
|
||||
dotnet pack . -c Release
|
||||
```
|
||||
|
||||
To package the .NET extension for NORM that targets 64-bit Windows, execute the command in the src/dotnet directory:
|
||||
|
||||
```
|
||||
pack-win-x64.bat
|
||||
```
|
||||
|
||||
To package the .NET extension for NORM that targets 32-bit Windows, execute the command in the src/dotnet directory:
|
||||
|
||||
```
|
||||
pack-win-x86.bat
|
||||
```
|
||||
|
||||
To package the .NET extension for NORM that targets 64-bit Linux, execute the command in the src/dotnet directory:
|
||||
|
||||
```
|
||||
./pack-linux-x64.sh
|
||||
```
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33213.308
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mil.Navy.Nrl.Norm", "src\Mil.Navy.Nrl.Norm\Mil.Navy.Nrl.Norm.csproj", "{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A6F15F54-6953-49E7-9394-8F6BF6EF64D0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mil.Navy.Nrl.Norm.IntegrationTests", "tests\Mil.Navy.Nrl.Norm.IntegrationTests\Mil.Navy.Nrl.Norm.IntegrationTests.csproj", "{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{8B6C912C-2A15-41F3-B3A4-E9C01E6672DE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mil.Navy.Nrl.Norm.win-x64", "src\Mil.Navy.Nrl.Norm.win-x64\Mil.Navy.Nrl.Norm.win-x64.csproj", "{EC81BD1A-ECF0-4F4D-86E3-B0B53531EBD4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mil.Navy.Nrl.Norm.win-x86", "src\Mil.Navy.Nrl.Norm.win-x86\Mil.Navy.Nrl.Norm.win-x86.csproj", "{E5EABC55-159A-4AA2-80EC-F817C20BDA40}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CD4475A5-559A-4852-A2FE-E85A8AB9E0D8}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
pack-linux.sh = pack-linux.sh
|
||||
pack-win32.bat = pack-win32.bat
|
||||
pack-win64.bat = pack-win64.bat
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mil.Navy.Nrl.Norm.linux-x64", "src\Mil.Navy.Nrl.Norm.linux-x64\Mil.Navy.Nrl.Norm.linux-x64.csproj", "{A4967E0C-FF3E-4B61-BD6B-D63D040585CA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release-linux-x64|Any CPU = Release-linux-x64|Any CPU
|
||||
Release-win-x64|Any CPU = Release-win-x64|Any CPU
|
||||
Release-win-x86|Any CPU = Release-win-x86|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Release-linux-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Release-linux-x64|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Release-win-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Release-win-x64|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Release-win-x86|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F}.Release-win-x86|Any CPU.Build.0 = Release|Any CPU
|
||||
{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49}.Release-linux-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49}.Release-win-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49}.Release-win-x86|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC81BD1A-ECF0-4F4D-86E3-B0B53531EBD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EC81BD1A-ECF0-4F4D-86E3-B0B53531EBD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC81BD1A-ECF0-4F4D-86E3-B0B53531EBD4}.Release-linux-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC81BD1A-ECF0-4F4D-86E3-B0B53531EBD4}.Release-win-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC81BD1A-ECF0-4F4D-86E3-B0B53531EBD4}.Release-win-x64|Any CPU.Build.0 = Release|Any CPU
|
||||
{EC81BD1A-ECF0-4F4D-86E3-B0B53531EBD4}.Release-win-x86|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5EABC55-159A-4AA2-80EC-F817C20BDA40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E5EABC55-159A-4AA2-80EC-F817C20BDA40}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5EABC55-159A-4AA2-80EC-F817C20BDA40}.Release-linux-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5EABC55-159A-4AA2-80EC-F817C20BDA40}.Release-win-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5EABC55-159A-4AA2-80EC-F817C20BDA40}.Release-win-x86|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5EABC55-159A-4AA2-80EC-F817C20BDA40}.Release-win-x86|Any CPU.Build.0 = Release|Any CPU
|
||||
{A4967E0C-FF3E-4B61-BD6B-D63D040585CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A4967E0C-FF3E-4B61-BD6B-D63D040585CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A4967E0C-FF3E-4B61-BD6B-D63D040585CA}.Release-linux-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A4967E0C-FF3E-4B61-BD6B-D63D040585CA}.Release-linux-x64|Any CPU.Build.0 = Release|Any CPU
|
||||
{A4967E0C-FF3E-4B61-BD6B-D63D040585CA}.Release-win-x64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A4967E0C-FF3E-4B61-BD6B-D63D040585CA}.Release-win-x86|Any CPU.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{0B38FE25-685E-4ADC-B63D-CA43EC023E1F} = {A6F15F54-6953-49E7-9394-8F6BF6EF64D0}
|
||||
{E5CDA4C5-C1A1-4AD7-B10D-80B8A995FC49} = {8B6C912C-2A15-41F3-B3A4-E9C01E6672DE}
|
||||
{EC81BD1A-ECF0-4F4D-86E3-B0B53531EBD4} = {A6F15F54-6953-49E7-9394-8F6BF6EF64D0}
|
||||
{E5EABC55-159A-4AA2-80EC-F817C20BDA40} = {A6F15F54-6953-49E7-9394-8F6BF6EF64D0}
|
||||
{A4967E0C-FF3E-4B61-BD6B-D63D040585CA} = {A6F15F54-6953-49E7-9394-8F6BF6EF64D0}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8BC1F27F-D633-4B45-A16D-D112CB08840E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@startuml
|
||||
abstract class ByteBuffer {
|
||||
# ByteBuffer()
|
||||
+ {static} AllocateDirect(capacity:int) : ByteBuffer
|
||||
}
|
||||
SafeBuffer <|-- ByteBuffer
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@startuml
|
||||
class DirectByteBuffer <<sealed>> {
|
||||
<<internal>> DirectByteBuffer(capacity:int)
|
||||
# <<override>> ReleaseHandle() : bool
|
||||
}
|
||||
ByteBuffer <|-- DirectByteBuffer
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
@startuml
|
||||
enum NormAckingStatus {
|
||||
NORM_ACK_INVALID,
|
||||
NORM_ACK_FAILURE,
|
||||
NORM_ACK_PENDING,
|
||||
NORM_ACK_SUCCESS,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
@startuml
|
||||
enum NormEventType {
|
||||
NORM_EVENT_INVALID,
|
||||
NORM_TX_QUEUE_VACANCY,
|
||||
NORM_TX_QUEUE_EMPTY,
|
||||
NORM_TX_FLUSH_COMPLETED,
|
||||
NORM_TX_WATERMARK_COMPLETED,
|
||||
NORM_TX_CMD_SENT,
|
||||
NORM_TX_OBJECT_SENT,
|
||||
NORM_TX_OBJECT_PURGED,
|
||||
NORM_TX_RATE_CHANGED,
|
||||
NORM_LOCAL_SENDER_CLOSED,
|
||||
NORM_REMOTE_SENDER_NEW,
|
||||
NORM_REMOTE_SENDER_RESET,
|
||||
NORM_REMOTE_SENDER_ADDRESS,
|
||||
NORM_REMOTE_SENDER_ACTIVE,
|
||||
NORM_REMOTE_SENDER_INACTIVE,
|
||||
NORM_REMOTE_SENDER_PURGED,
|
||||
NORM_RX_CMD_NEW,
|
||||
NORM_RX_OBJECT_NEW,
|
||||
NORM_RX_OBJECT_INFO,
|
||||
NORM_RX_OBJECT_UPDATED,
|
||||
NORM_RX_OBJECT_COMPLETED,
|
||||
NORM_RX_OBJECT_ABORTED,
|
||||
NORM_RX_ACK_REQUEST,
|
||||
NORM_GRTT_UPDATED,
|
||||
NORM_CC_ACTIVE,
|
||||
NORM_CC_INACTIVE,
|
||||
NORM_ACKING_NODE_NEW,
|
||||
NORM_SEND_ERROR,
|
||||
NORM_USER_TIMEOUT,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@startuml
|
||||
enum NormFecType {
|
||||
RS,
|
||||
RS8,
|
||||
SB,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@startuml
|
||||
enum NormFlushMode {
|
||||
NORM_FLUSH_NONE,
|
||||
NORM_FLUSH_PASSIVE,
|
||||
NORM_FLUSH_ACTIVE,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@startuml
|
||||
enum NormNackingMode {
|
||||
NORM_NACK_NONE,
|
||||
NORM_NACK_INFO_ONLY,
|
||||
NORM_NACK_NORMAL,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
@startuml
|
||||
enum NormObjectType {
|
||||
NORM_OBJECT_NONE,
|
||||
NORM_OBJECT_DATA,
|
||||
NORM_OBJECT_FILE,
|
||||
NORM_OBJECT_STREAM,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@startuml
|
||||
enum NormProbingMode {
|
||||
NORM_PROBE_NONE,
|
||||
NORM_PROBE_PASSIVE,
|
||||
NORM_PROBE_ACTIVE,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
@startuml
|
||||
enum NormRepairBoundary {
|
||||
NORM_BOUNDARY_BLOCK,
|
||||
NORM_BOUNDARY_OBJECT,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@startuml
|
||||
enum NormSyncPolicy {
|
||||
NORM_SYNC_CURRENT,
|
||||
NORM_SYNC_STREAM,
|
||||
NORM_SYNC_ALL,
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
@startuml
|
||||
enum NormTrackingStatus
|
||||
{
|
||||
NORM_TRACK_NONE
|
||||
NORM_TRACK_RECEIVERS
|
||||
NORM_TRACK_SENDERS
|
||||
NORM_TRACK_ALL
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
@startuml
|
||||
interface INormEventListener {
|
||||
NormEventOccurred(normEvent:NormEvent) : void
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
@startuml
|
||||
class NormInputStream {
|
||||
- _normStream : NormStream?
|
||||
- _closed : bool
|
||||
- _closeLock : object
|
||||
- _bufferIsEmpty : bool
|
||||
- _receivedEof : bool
|
||||
+ NormInputStream(address:string, port:int)
|
||||
+ OpenDebugLog(fileName:string) : void
|
||||
+ CloseDebugLog() : void
|
||||
+ NormSetDebugLevel(level:int) : void
|
||||
+ SetMessageTrace(messageTrace:bool) : void
|
||||
+ SetMulticastInterface(multicastInterface:string) : void
|
||||
+ SetEcnSupport(ecnEnable:bool, ignoreLoss:bool) : void
|
||||
+ SetTtl(ttl:byte) : void
|
||||
+ SetTos(tos:byte) : void
|
||||
+ setSilentReceiver(silent:bool, maxDelay:int) : void
|
||||
+ SetDefaultUnicastNack(defaultUnicastNack:bool) : void
|
||||
+ SeekMsgStart() : void
|
||||
+ AddNormEventListener(normEventListener:INormEventListener) : void
|
||||
+ RemoveNormEventListener(normEventListener:INormEventListener) : void
|
||||
- FireNormEventOccured(normEvent:NormEvent) : void
|
||||
+ Open(bufferSpace:long) : void
|
||||
+ <<override>> Close() : void
|
||||
+ IsClosed : bool <<get>>
|
||||
+ Read() : int
|
||||
+ <<override>> Read(buffer:byte[], offset:int, count:int) : int
|
||||
- ProcessEvent() : void
|
||||
+ <<override>> Flush() : void
|
||||
+ <<override>> Write(buffer:byte[], offset:int, count:int) : void
|
||||
+ <<override>> Seek(offset:long, origin:SeekOrigin) : long
|
||||
+ <<override>> SetLength(value:long) : void
|
||||
+ <<override>> CanRead : bool <<get>>
|
||||
+ <<override>> CanSeek : bool <<get>>
|
||||
+ <<override>> CanWrite : bool <<get>>
|
||||
+ <<override>> Length : long <<get>>
|
||||
+ <<override>> Position : long <<get>> <<set>>
|
||||
}
|
||||
class "List`1"<T> {
|
||||
}
|
||||
Stream <|-- NormInputStream
|
||||
NormInputStream --> "_normInstance" NormInstance
|
||||
NormInputStream --> "_normSession" NormSession
|
||||
NormInputStream --> "_normEventListeners<INormEventListener>" "List`1"
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
@startuml
|
||||
class NormOutputStream {
|
||||
- _normStream : NormStream?
|
||||
- _closed : bool
|
||||
- _closeLock : object
|
||||
- _bufferIsFull : bool
|
||||
+ NormOutputStream(address:string, port:int)
|
||||
+ OpenDebugLog(filename:string) : void
|
||||
+ CloseDebugLog() : void
|
||||
+ SetDebugLevel(level:int) : void
|
||||
+ SetMessageTrace(messageTrace:bool) : void
|
||||
+ SetMulticastInterface(multicastInterface:string) : void
|
||||
+ SetEcnSupport(ecnEnable:bool, ignoreLoss:bool) : void
|
||||
+ SetTtl(ttl:byte) : void
|
||||
+ SetTos(tos:byte) : void
|
||||
+ SetCongestionControl(ccEnabled:bool, ccAdjustRate:bool) : void
|
||||
+ SetTxRateBounds(minTxRate:double, maxTxRate:double) : void
|
||||
+ TxRate : double <<get>> <<set>>
|
||||
+ GrttEstimate : double <<get>> <<set>>
|
||||
+ SetGroupSize(groupSize:long) : void
|
||||
+ SetAutoParity(autoParity:short) : void
|
||||
+ SetBackoffFactor(backoffFactor:double) : void
|
||||
+ SetAutoFlush(flushMode:NormFlushMode) : void
|
||||
+ SetPushEnable(pushEnable:bool) : void
|
||||
+ MarkEom() : void
|
||||
+ AddNormEventListener(normEventListener:INormEventListener) : void
|
||||
+ RemoveNormEventListener(normEventListener:INormEventListener) : void
|
||||
- FireNormEventOccured(normEvent:NormEvent) : void
|
||||
+ Open(sessionId:int, bufferSpace:long, segmentSize:int, blockSize:short, numParity:short, repairWindow:long) : void
|
||||
+ <<override>> Close() : void
|
||||
+ IsClosed : bool <<get>>
|
||||
+ Write(b:int) : void
|
||||
+ <<override>> Write(buffer:byte[], offset:int, count:int) : void
|
||||
- ProcessEvent() : void
|
||||
+ <<override>> Flush() : void
|
||||
+ <<override>> Read(buffer:byte[], offset:int, count:int) : int
|
||||
+ <<override>> Seek(offset:long, origin:SeekOrigin) : long
|
||||
+ <<override>> SetLength(value:long) : void
|
||||
+ <<override>> CanRead : bool <<get>>
|
||||
+ <<override>> CanSeek : bool <<get>>
|
||||
+ <<override>> CanWrite : bool <<get>>
|
||||
+ <<override>> Length : long <<get>>
|
||||
+ <<override>> Position : long <<get>> <<set>>
|
||||
}
|
||||
class "List`1"<T> {
|
||||
}
|
||||
Stream <|-- NormOutputStream
|
||||
NormOutputStream --> "_normInstance" NormInstance
|
||||
NormOutputStream --> "_normSession" NormSession
|
||||
NormOutputStream --> "_normEventListeners<INormEventListener>" "List`1"
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
@startuml
|
||||
class StreamBreakException {
|
||||
+ StreamBreakException(message:string?)
|
||||
}
|
||||
IOException <|-- StreamBreakException
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
@startuml
|
||||
class NormApi <<static>> {
|
||||
+ <<const>> NORM_LIBRARY : string = "norm"
|
||||
+ {static} <<extern>> NormCreateInstance(priorityBoost:bool) : long
|
||||
+ {static} <<extern>> NormDestroyInstance(instanceHandle:long) : void
|
||||
+ {static} <<extern>> NormStopInstance(instanceHandle:long) : void
|
||||
+ {static} <<extern>> NormRestartInstance(instanceHandle:long) : bool
|
||||
+ {static} <<extern>> NormSuspendInstance(instanceHandle:long) : bool
|
||||
+ {static} <<extern>> NormResumeInstance(instanceHandle:long) : bool
|
||||
+ {static} <<extern>> NormSetCacheDirectory(instanceHandle:long, cachePath:string) : bool
|
||||
+ {static} <<extern>> NormGetNextEvent(instanceHandle:long, theEvent:NormEvent, waitForEvent:bool) : bool
|
||||
+ {static} <<extern>> NormGetDescriptor(instanceHandle:long) : int
|
||||
+ {static} <<extern>> NormCreateSession(instanceHandle:long, sessionAddress:string, sessionPort:int, localNodeId:long) : long
|
||||
+ {static} <<extern>> NormDestroySession(sessionHandle:long) : void
|
||||
+ {static} <<extern>> NormGetLocalNodeId(sessionHandle:long) : long
|
||||
+ {static} <<extern>> NormSetTxPort(sessionHandle:long, txPortNumber:int, enableReuse:bool, txBindAddress:string?) : bool
|
||||
+ {static} <<extern>> NormSetTxOnly(sessionHandle:long, txOnly:bool, connectToSessionAddress:bool) : void
|
||||
+ {static} <<extern>> NormSetRxPortReuse(sessionHandle:long, enableReuse:bool, rxBindAddress:string?, senderAddress:string?, senderPort:int) : void
|
||||
+ {static} <<extern>> NormSetEcnSupport(sessionHandle:long, ecnEnable:bool, ignoreLoss:bool, tolerateLoss:bool) : void
|
||||
+ {static} <<extern>> NormSetMulticastInterface(sessionHandle:long, interfaceName:string) : bool
|
||||
+ {static} <<extern>> NormSetSSM(sessionHandle:long, sourceAddress:string) : bool
|
||||
+ {static} <<extern>> NormSetTTL(sessionHandle:long, ttl:byte) : bool
|
||||
+ {static} <<extern>> NormSetTOS(sessionHandle:long, tos:byte) : bool
|
||||
+ {static} <<extern>> NormSetLoopback(sessionHandle:long, loopback:bool) : bool
|
||||
+ {static} <<extern>> NormSetMessageTrace(sessionHandle:long, flag:bool) : void
|
||||
+ {static} <<extern>> NormSetTxLoss(sessionHandle:long, precent:double) : void
|
||||
+ {static} <<extern>> NormSetRxLoss(sessionHandle:long, precent:double) : void
|
||||
+ {static} <<extern>> NormOpenDebugLog(instanceHandle:long, path:string) : bool
|
||||
+ {static} <<extern>> NormCloseDebugLog(instanceHandle:long) : bool
|
||||
+ {static} <<extern>> NormOpenDebugPipe(instanceHandle:long, pipeName:string) : bool
|
||||
+ {static} <<extern>> NormSetDebugLevel(level:int) : void
|
||||
+ {static} <<extern>> NormGetDebugLevel() : int
|
||||
+ {static} <<extern>> NormSetReportInterval(sessionHandle:long, interval:double) : void
|
||||
+ {static} <<extern>> NormGetReportInterval(sessionHandle:long) : double
|
||||
+ {static} <<extern>> NormGetRandomSessionId() : int
|
||||
+ {static} <<extern>> NormStartSender(instanceHandle:long, instanceId:int, bufferSpace:long, segmentSize:int, numData:short, numParity:short, fecId:NormFecType) : bool
|
||||
+ {static} <<extern>> NormStopSender(sessionHandle:long) : void
|
||||
+ {static} <<extern>> NormSetTxRate(sessionHandle:long, rate:double) : void
|
||||
+ {static} <<extern>> NormGetTxRate(sessionHandle:long) : double
|
||||
+ {static} <<extern>> NormSetTxSocketBuffer(sessionHandle:long, bufferSize:long) : bool
|
||||
+ {static} <<extern>> NormSetFlowControl(sessionHandle:long, flowControlFactor:double) : void
|
||||
+ {static} <<extern>> NormSetCongestionControl(sessionHandle:long, enable:bool, adjustRate:bool) : void
|
||||
+ {static} <<extern>> NormSetTxRateBounds(sessionHandle:long, rateMin:double, rateMax:double) : void
|
||||
+ {static} <<extern>> NormSetTxCacheBounds(sessionHandle:long, sizeMax:long, countMin:long, countMax:long) : void
|
||||
+ {static} <<extern>> NormSetAutoParity(sesssionHandle:long, autoParity:short) : void
|
||||
+ {static} <<extern>> NormSetGrttEstimate(sessionHandle:long, grtt:double) : void
|
||||
+ {static} <<extern>> NormGetGrttEstimate(sessionHandle:long) : double
|
||||
+ {static} <<extern>> NormSetGrttMax(sessionHandle:long, grttMax:double) : void
|
||||
+ {static} <<extern>> NormSetGrttProbingMode(sesssionHandle:long, probingMode:NormProbingMode) : void
|
||||
+ {static} <<extern>> NormSetGrttProbingInterval(sessionHandle:long, intervalMin:double, intervalMax:double) : void
|
||||
+ {static} <<extern>> NormSetBackoffFactor(sessionHandle:long, backoffFactor:double) : void
|
||||
+ {static} <<extern>> NormSetGroupSize(sessionHandle:long, groupSize:long) : void
|
||||
+ {static} <<extern>> NormSetTxRobustFactor(sessionHandle:long, txRobustFactor:int) : void
|
||||
+ {static} <<extern>> NormFileEnqueue(sessionHandle:long, fileName:string, infoPtr:nint, infoLen:int) : long
|
||||
+ {static} <<extern>> NormDataEnqueue(sessionHandle:long, dataPtr:nint, dataLen:int, infoPtr:nint, infoLen:int) : long
|
||||
+ {static} <<extern>> NormRequeueObject(sessionHandle:long, objectHandle:long) : bool
|
||||
+ {static} <<extern>> NormStreamOpen(sessionHandle:long, bufferSize:long, infoPtr:nint, infoLen:int) : long
|
||||
+ {static} <<extern>> NormStreamClose(streamHandle:long, graceful:bool) : void
|
||||
+ <<unsafe>> {static} <<extern>> NormStreamWrite(streamHandle:long, buffer:byte*, numBytes:int) : int
|
||||
+ {static} <<extern>> NormStreamFlush(streamHandle:long, eom:bool, flushMode:NormFlushMode) : void
|
||||
+ {static} <<extern>> NormStreamSetAutoFlush(streamHandle:long, flushMode:NormFlushMode) : void
|
||||
+ {static} <<extern>> NormStreamSetPushEnable(streamHandle:long, pushEnable:bool) : void
|
||||
+ {static} <<extern>> NormStreamHasVacancy(streamHandle:long) : bool
|
||||
+ {static} <<extern>> NormStreamMarkEom(streamHandle:long) : void
|
||||
+ {static} <<extern>> NormSetWatermark(sessionHandle:long, objectHandle:long, overrideFlush:bool) : bool
|
||||
+ {static} <<extern>> NormResetWatermark(sessionHandle:long) : bool
|
||||
+ {static} <<extern>> NormCancelWatermark(sessionHandle:long) : void
|
||||
+ {static} <<extern>> NormAddAckingNode(sessionHandle:long, nodeId:long) : bool
|
||||
+ {static} <<extern>> NormRemoveAckingNode(sessionHandle:long, nodeId:long) : void
|
||||
+ {static} <<extern>> NormGetAckingStatus(sessionHandle:long, nodeId:long) : NormAckingStatus
|
||||
+ {static} <<extern>> NormSendCommand(sessionHandle:long, cmdBuffer:nint, cmdLength:int, robust:bool) : bool
|
||||
+ {static} <<extern>> NormCancelCommand(sessionHandle:long) : void
|
||||
+ {static} <<extern>> NormStartReceiver(sessionHandle:long, bufferSpace:long) : bool
|
||||
+ {static} <<extern>> NormStopReceiver(sessionHandle:long) : void
|
||||
+ {static} <<extern>> NormSetRxCacheLimit(sessionHandle:long, countMax:int) : void
|
||||
+ {static} <<extern>> NormSetRxSocketBuffer(sessionHandle:long, bufferSize:long) : bool
|
||||
+ {static} <<extern>> NormSetSilentReceiver(sessionHandle:long, silent:bool, maxDelay:int) : void
|
||||
+ {static} <<extern>> NormSetDefaultUnicastNack(sessionHandle:long, unicastNacks:bool) : void
|
||||
+ {static} <<extern>> NormNodeSetUnicastNack(remoteSender:long, unicastNacks:bool) : void
|
||||
+ {static} <<extern>> NormSetDefaultSyncPolicy(sessionHandle:long, syncPolicy:NormSyncPolicy) : void
|
||||
+ {static} <<extern>> NormSetDefaultNackingMode(sessionHandle:long, nackingMode:NormNackingMode) : void
|
||||
+ {static} <<extern>> NormNodeSetNackingMode(remoteSender:long, nackingMode:NormNackingMode) : void
|
||||
+ {static} <<extern>> NormObjectSetNackingMode(objectHandle:long, nackingMode:NormNackingMode) : void
|
||||
+ {static} <<extern>> NormSetDefaultRepairBoundary(sessionHandle:long, repairBoundary:NormRepairBoundary) : void
|
||||
+ {static} <<extern>> NormNodeSetRepairBoundary(remoteSender:long, repairBoundary:NormRepairBoundary) : void
|
||||
+ {static} <<extern>> NormSetDefaultRxRobustFactor(sessionHandle:long, robustFactor:int) : void
|
||||
+ {static} <<extern>> NormNodeSetRxRobustFactor(remoteSender:long, robustFactor:int) : void
|
||||
+ <<unsafe>> {static} <<extern>> NormStreamRead(streamHandle:long, buffer:byte*, numBytes:int) : bool
|
||||
+ {static} <<extern>> NormStreamSeekMsgStart(streamHandle:long) : bool
|
||||
+ {static} <<extern>> NormStreamGetReadOffset(streamHandle:long) : long
|
||||
+ {static} <<extern>> NormObjectGetType(objectHandle:long) : NormObjectType
|
||||
+ {static} <<extern>> NormObjectHasInfo(objectHandle:long) : bool
|
||||
+ {static} <<extern>> NormObjectGetInfoLength(objectHandle:long) : int
|
||||
+ {static} <<extern>> NormObjectGetInfo(objectHandle:long, buffer:byte[], bufferLen:int) : int
|
||||
+ {static} <<extern>> NormObjectGetSize(objectHandle:long) : int
|
||||
+ {static} <<extern>> NormObjectGetBytesPending(objectHandle:long) : long
|
||||
+ {static} <<extern>> NormObjectCancel(objectHandle:long) : void
|
||||
+ {static} <<extern>> NormObjectRetain(objectHandle:long) : void
|
||||
+ {static} <<extern>> NormObjectRelease(objectHandle:long) : void
|
||||
+ <<unsafe>> {static} <<extern>> NormFileGetName(fileHandle:long, nameBuffer:sbyte*, bufferLen:int) : bool
|
||||
+ {static} <<extern>> NormFileRename(fileHandle:long, fileName:string) : bool
|
||||
+ {static} <<extern>> NormDataAccessData(objectHandle:long) : nint
|
||||
+ {static} <<extern>> NormObjectGetSender(objectHandle:long) : long
|
||||
+ {static} <<extern>> NormNodeGetId(nodeHandle:long) : long
|
||||
+ <<unsafe>> {static} <<extern>> NormNodeGetAddress(nodeHandle:long, addrBuffer:byte*, bufferLen:int, port:int) : bool
|
||||
+ {static} <<extern>> NormNodeGetGrtt(nodeHandle:long) : double
|
||||
+ <<unsafe>> {static} <<extern>> NormNodeGetCommand(remoteSender:long, cmdBuffer:byte*, buflen:int) : bool
|
||||
+ {static} <<extern>> NormNodeFreeBuffers(remoteSender:long) : void
|
||||
+ {static} <<extern>> NormNodeRetain(nodeHandle:long) : void
|
||||
+ {static} <<extern>> NormNodeRelease(nodeHandle:long) : void
|
||||
}
|
||||
struct NormEvent {
|
||||
+ Session : long
|
||||
+ Sender : long
|
||||
+ Object : long
|
||||
}
|
||||
NormApi +-- NormEvent
|
||||
NormEvent --> "Type" NormEventType
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@startuml
|
||||
class NormData {
|
||||
+ GetData() : byte[]
|
||||
<<internal>> NormData(handle:long)
|
||||
}
|
||||
NormObject <|-- NormData
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
@startuml
|
||||
class NormEvent {
|
||||
- _sessionHandle : long <<get>>
|
||||
- _nodeHandle : long <<get>>
|
||||
- _objectHandle : long <<get>>
|
||||
+ NormEvent(type:NormEventType, sessionHandle:long, nodeHandle:long, objectHandle:long)
|
||||
+ <<override>> ToString() : string
|
||||
}
|
||||
NormEvent --> "_type" NormEventType
|
||||
NormEvent --> "Type" NormEventType
|
||||
NormEvent --> "Session" NormSession
|
||||
NormEvent --> "Node" NormNode
|
||||
NormEvent --> "Object" NormObject
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
@startuml
|
||||
class NormFile {
|
||||
+ <<const>> FILENAME_MAX : int = 260
|
||||
<<internal>> NormFile(handle:long)
|
||||
+ <<unsafe>> Name : string <<get>>
|
||||
+ Rename(filePath:string) : void
|
||||
}
|
||||
NormObject <|-- NormFile
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
@startuml
|
||||
class NormInstance {
|
||||
+ <<const>> NORM_DESCRIPTOR_INVALID : int = 0
|
||||
- _handle : long
|
||||
+ NormInstance(priorityBoost:bool)
|
||||
+ NormInstance()
|
||||
- CreateInstance(priorityBoost:bool) : void
|
||||
+ DestroyInstance() : void
|
||||
+ CreateSession(address:string, port:int, localNodeId:long) : NormSession
|
||||
+ HasNextEvent(sec:int, usec:int) : bool
|
||||
+ HasNextEvent(waitTime:TimeSpan) : bool
|
||||
+ GetNextEvent(waitForEvent:bool) : NormEvent?
|
||||
+ GetNextEvent() : NormEvent?
|
||||
+ SetCacheDirectory(cachePath:string) : void
|
||||
+ StopInstance() : void
|
||||
+ RestartInstance() : bool
|
||||
+ SuspendInstance() : bool
|
||||
+ ResumeInstance() : void
|
||||
+ OpenDebugLog(fileName:string) : void
|
||||
+ CloseDebugLog() : void
|
||||
+ OpenDebugPipe(pipename:string) : void
|
||||
+ DebugLevel : int <<get>> <<set>>
|
||||
}
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
@startuml
|
||||
class NormNode {
|
||||
+ <<const>> NORM_NODE_ANY : long = 0xffffffff
|
||||
+ <<const>> NORM_NODE_NONE : int = 0
|
||||
+ <<const>> NORM_NODE_INVALID : int = 0
|
||||
- _handle : long
|
||||
<<internal>> NormNode(handle:long)
|
||||
+ Id : long <<get>>
|
||||
+ Grtt : double <<get>>
|
||||
+ GetCommand(buffer:byte[], offset:int, length:int) : int
|
||||
+ SetUnicastNack(state:bool) : void
|
||||
+ SetNackingMode(nackingMode:NormNackingMode) : void
|
||||
+ SetRepairBoundary(repairBoundary:NormRepairBoundary) : void
|
||||
+ SetRxRobustFactor(robustFactor:int) : void
|
||||
+ FreeBuffers() : void
|
||||
+ Retain() : void
|
||||
+ Release() : void
|
||||
}
|
||||
NormNode --> "Address" IPEndPoint
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
@startuml
|
||||
class NormObject {
|
||||
+ <<const>> NORM_OBJECT_INVALID : int = 0
|
||||
# _handle : long
|
||||
<<internal>> NormObject(handle:long)
|
||||
+ Handle : long <<get>>
|
||||
+ Info : byte[] <<get>>
|
||||
+ Size : long <<get>>
|
||||
+ Sender : long <<get>>
|
||||
+ SetNackingMode(nackingMode:NormNackingMode) : void
|
||||
+ GetBytesPending() : long
|
||||
+ Cancel() : void
|
||||
+ Retain() : void
|
||||
+ Release() : void
|
||||
+ <<override>> GetHashCode() : int
|
||||
+ <<override>> Equals(obj:object?) : bool
|
||||
}
|
||||
NormObject --> "Type" NormObjectType
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
@startuml
|
||||
class NormSession {
|
||||
+ <<const>> NORM_SESSION_INVALID : int = 0
|
||||
- _handle : long
|
||||
+ LocalNodeId : long <<get>>
|
||||
+ ReportInterval : double <<get>> <<set>>
|
||||
+ TxRate : double <<get>> <<set>>
|
||||
+ GrttEstimate : double <<get>> <<set>>
|
||||
<<internal>> NormSession(handle:long)
|
||||
<<internal>> {static} GetSession(handle:long) : NormSession?
|
||||
+ DestroySession() : void
|
||||
- DestroySessionNative() : void
|
||||
+ SetTxPort(port:int) : void
|
||||
+ SetTxPort(port:int, enableReuse:bool, txBindAddress:string?) : void
|
||||
+ SetTxOnly(txOnly:bool) : void
|
||||
+ SetTxOnly(txOnly:bool, connectToSessionAddress:bool) : void
|
||||
+ SetRxPortReuse(enable:bool) : void
|
||||
+ SetRxPortReuse(enable:bool, rxBindAddress:string?, senderAddress:string?, senderPort:int) : void
|
||||
+ SetEcnSupport(ecnEnable:bool, ignoreLoss:bool) : void
|
||||
+ SetEcnSupport(ecnEnable:bool, ignoreLoss:bool, tolerateLoss:bool) : void
|
||||
+ SetMulticastInterface(interfaceName:string) : void
|
||||
+ SetSSM(sourceAddress:string) : void
|
||||
+ SetTTL(ttl:byte) : void
|
||||
+ SetTOS(tos:byte) : void
|
||||
+ SetLoopback(loopbackEnable:bool) : void
|
||||
+ SetMessageTrace(flag:bool) : void
|
||||
+ SetTxLoss(precent:double) : void
|
||||
+ SetRxLoss(precent:double) : void
|
||||
+ SetFlowControl(precent:double) : void
|
||||
+ SetTxSocketBuffer(bufferSize:long) : void
|
||||
+ SetCongestionControl(enable:bool) : void
|
||||
+ SetCongestionControl(enable:bool, adjustRate:bool) : void
|
||||
+ SetTxRateBounds(rateMin:double, rateMax:double) : void
|
||||
+ SetTxCacheBounds(sizeMax:long, countMin:long, countMax:long) : void
|
||||
+ StartSender(sessionId:int, bufferSpace:long, segmentSize:int, blockSize:short, numParity:short, fecId:NormFecType) : void
|
||||
+ StartSender(sessionId:int, bufferSpace:long, segmentSize:int, blockSize:short, numParity:short) : void
|
||||
+ StartSender(bufferSpace:long, segmentSize:int, blockSize:short, numParity:short, fecId:NormFecType) : void
|
||||
+ StartSender(bufferSpace:long, segmentSize:int, blockSize:short, numParity:short) : void
|
||||
+ StopSender() : void
|
||||
+ FileEnqueue(filename:string) : NormFile
|
||||
+ FileEnqueue(filename:string, info:byte[]?, infoOffset:int, infoLength:int) : NormFile
|
||||
+ DataEnqueue(dataBuffer:SafeBuffer, dataOffset:int, dataLength:int) : NormData
|
||||
+ DataEnqueue(dataBuffer:SafeBuffer, dataOffset:int, dataLength:int, info:byte[]?, infoOffset:int, infoLength:int) : NormData
|
||||
+ DataEnqueue(dataPtr:nint, dataOffset:int, dataLength:int) : NormData
|
||||
+ DataEnqueue(dataPtr:nint, dataOffset:int, dataLength:int, info:byte[]?, infoOffset:int, infoLength:int) : NormData
|
||||
+ StreamOpen(bufferSize:long) : NormStream
|
||||
+ StreamOpen(bufferSize:long, info:byte[]?, infoOffset:int, infoLength:int) : NormStream
|
||||
+ StartReceiver(bufferSpace:long) : void
|
||||
+ StopReceiver() : void
|
||||
+ SetAutoParity(autoParity:short) : void
|
||||
+ SetGrttMax(grttMax:double) : void
|
||||
+ SetGrttProbingMode(probingMode:NormProbingMode) : void
|
||||
+ SetGrttProbingInterval(intervalMin:double, intervalMax:double) : void
|
||||
+ SetBackoffFactor(backoffFactor:double) : void
|
||||
+ SetGroupSize(groupSize:long) : void
|
||||
+ SetTxRobustFactor(txRobustFactor:int) : void
|
||||
+ RequeueObject(normObject:NormObject) : void
|
||||
+ SetWatermark(normObject:NormObject) : void
|
||||
+ SetWatermark(normObject:NormObject, overrideFlush:bool) : void
|
||||
+ CancelWatermark() : void
|
||||
+ ResetWatermark() : void
|
||||
+ AddAckingNode(nodeId:long) : void
|
||||
+ RemoveAckingNode(nodeId:long) : void
|
||||
+ GetAckingStatus(nodeId:long) : NormAckingStatus
|
||||
+ SendCommand(cmdBuffer:byte[], cmdOffset:int, cmdLength:int, robust:bool) : void
|
||||
+ CancelCommand() : void
|
||||
+ SetRxCacheLimit(countMax:int) : void
|
||||
+ SetRxSocketBuffer(bufferSize:long) : void
|
||||
+ SetSilentReceiver(silent:bool, maxDelay:int) : void
|
||||
+ SetDefaultUnicastNack(enable:bool) : void
|
||||
+ SetDefaultSyncPolicy(syncPolicy:NormSyncPolicy) : void
|
||||
+ SetDefaultNackingMode(nackingMode:NormNackingMode) : void
|
||||
+ SetDefaultRepairBoundary(repairBoundary:NormRepairBoundary) : void
|
||||
+ SetDefaultRxRobustFactor(rxRobustFactor:int) : void
|
||||
}
|
||||
class "Dictionary`2"<T1,T2> {
|
||||
}
|
||||
NormSession o-> "_normSessions<long,NormSession>" "Dictionary`2"
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
@startuml
|
||||
class NormStream {
|
||||
+ HasVacancy : bool <<get>>
|
||||
+ ReadOffset : long <<get>>
|
||||
<<internal>> NormStream(handle:long)
|
||||
+ Write(buffer:byte[], offset:int, length:int) : int
|
||||
+ MarkEom() : void
|
||||
+ Flush(eom:bool, flushMode:NormFlushMode) : void
|
||||
+ Flush() : void
|
||||
+ Close(graceful:bool) : void
|
||||
+ Close() : void
|
||||
+ Read(buffer:byte[], offset:int, length:int) : int
|
||||
+ SeekMsgStart() : bool
|
||||
+ SetPushEnable(pushEnable:bool) : void
|
||||
+ SetAutoFlush(flushMode:NormFlushMode) : void
|
||||
}
|
||||
NormObject <|-- NormStream
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
@startuml NormFileSend
|
||||
Client -> NormInstance : new()
|
||||
NormInstance -> NormInstance : CreateInstance(false)
|
||||
NormInstance -> NormApi : NormCreateInstance(false)
|
||||
NormInstance <- NormApi : instanceHandle
|
||||
Client <- NormInstance : NormInstance
|
||||
Client -> NormInstance : CreateSession(address, port, localNodeId)
|
||||
NormInstance -> NormApi : NormCreateSession(instanceHandle, address, port, localNodeId)
|
||||
NormInstance <- NormApi : sessionHandle
|
||||
alt sessionHandle == NormApi.NORM_SESSION_INVALID
|
||||
NormInstance -> IOException : throw new("Failed to create session")
|
||||
end
|
||||
NormInstance -> NormSession : new(sessionHandle)
|
||||
NormInstance <- NormSession : NormSession
|
||||
Client <- NormInstance : NormSession
|
||||
Client -> NormSession : StartSender(sessionId, bufferSpace, segmentSize, blockSize, numParity, fecId)
|
||||
NormSession -> NormApi : NormStartSender(sessionHandle, sessionId, bufferSpace, segmentSize, blockSize, numParity, fecId)
|
||||
NormSession <- NormApi : success
|
||||
alt success == false
|
||||
NormSession -> IOException : throw new("Failed to start sender")
|
||||
end
|
||||
Client -> NormSession : FileEnqueue(filename)
|
||||
NormSession -> ASCII : GetBytes(filename)
|
||||
NormSession <- ASCII : info
|
||||
NormSession -> NormApi : NormFileEnqueue(sessionHandle, filename, info, info.Length)
|
||||
NormSession <- NormApi : objectHandle
|
||||
alt objectHandle == NormApi.NORM_OBJECT_INVALID
|
||||
NormSession -> IOException : throw new("Failed to enqueue file")
|
||||
end
|
||||
NormSession -> NormFile: new(objectHandle)
|
||||
NormSession <- NormFile : NormFile
|
||||
Client <- NormSession : NormFile
|
||||
loop NormInstance.HasNextEvent(waitTime)
|
||||
Client -> NormInstance : GetNextEvent(false)
|
||||
NormInstance -> NormApi : NormGetNextEvent(instanceHandle, NormEvent, false)
|
||||
NormInstance <- NormApi : success
|
||||
alt success == false
|
||||
Client <- NormInstance : null
|
||||
end
|
||||
Client <- NormInstance : NormEvent
|
||||
end
|
||||
Client -> NormSession : StopSender();
|
||||
NormSession -> NormApi : NormStopSender(sessionHandle)
|
||||
Client -> NormSession : DestroySession()
|
||||
NormSession -> NormSession : DestroySessionNative()
|
||||
NormSession -> NormApi : NormDestroySession(sessionHandle)
|
||||
Client -> NormInstance : DestroyInstance()
|
||||
NormInstance -> NormApi : NormDestroyInstance(instanceHandle)
|
||||
@enduml
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
currenPath="$PWD"
|
||||
cd ../../
|
||||
./waf
|
||||
cd "$currenPath"
|
||||
libPath="$currenPath/lib"
|
||||
if [ ! -d "$libPath" ]
|
||||
then
|
||||
mkdir "$libPath"
|
||||
fi
|
||||
cp -f ../../build/libnorm.so "$libPath/norm.so"
|
||||
dotnet pack . -c Release-linux-x64
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
set currenPath=%cd%
|
||||
cd ..\..\
|
||||
python .\waf configure --msvc_target=x64
|
||||
python .\waf
|
||||
cd %currenPath%
|
||||
if not exist lib\ (
|
||||
mkdir lib
|
||||
)
|
||||
copy ..\..\build\norm*.dll lib
|
||||
cd lib
|
||||
del /f norm.dll
|
||||
ren norm*.dll norm.dll
|
||||
cd %currenPath%
|
||||
dotnet pack . -c Release-win-x64
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
set currenPath=%cd%
|
||||
cd ..\..\
|
||||
python .\waf configure --msvc_target=x86
|
||||
python .\waf
|
||||
cd %currenPath%
|
||||
if not exist lib\ (
|
||||
mkdir lib
|
||||
)
|
||||
copy ..\..\build\norm*.dll lib
|
||||
cd lib
|
||||
del /f norm.dll
|
||||
ren norm*.dll norm.dll
|
||||
cd %currenPath%
|
||||
dotnet pack . -c Release-win-x86
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(SolutionDir)lib\norm.so">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<PackagePath>runtimes/linux-x64/native</PackagePath>
|
||||
<Pack>true</Pack>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Mil.Navy.Nrl.Norm\Mil.Navy.Nrl.Norm.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(SolutionDir)lib\norm.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<PackagePath>runtimes/win-x64/native</PackagePath>
|
||||
<Pack>true</Pack>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Mil.Navy.Nrl.Norm\Mil.Navy.Nrl.Norm.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(SolutionDir)lib\norm.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<PackagePath>runtimes/win-x86/native</PackagePath>
|
||||
<Pack>true</Pack>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Mil.Navy.Nrl.Norm\Mil.Navy.Nrl.Norm.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mil.Navy.Nrl.Norm.Buffers
|
||||
{
|
||||
/// <summary>
|
||||
/// A byte buffer
|
||||
/// </summary>
|
||||
public abstract class ByteBuffer : SafeBuffer
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new buffer
|
||||
/// </summary>
|
||||
protected ByteBuffer() : base(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allocates a new direct byte buffer
|
||||
/// </summary>
|
||||
/// <param name="capacity">The new buffer's capacity, in bytes</param>
|
||||
/// <returns>The new byte buffer</returns>
|
||||
public static ByteBuffer AllocateDirect(int capacity) {
|
||||
return new DirectByteBuffer(capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mil.Navy.Nrl.Norm.Buffers
|
||||
{
|
||||
/// <summary>
|
||||
/// A direct byte buffer
|
||||
/// </summary>
|
||||
internal sealed class DirectByteBuffer : ByteBuffer
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new direct byte buffer with given capacity
|
||||
/// </summary>
|
||||
/// <param name="capacity">The new buffer's capacity, in bytes</param>
|
||||
internal DirectByteBuffer(int capacity)
|
||||
{
|
||||
SetHandle(Marshal.AllocHGlobal(capacity));
|
||||
Initialize(Convert.ToUInt64(capacity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the code required to free the handle
|
||||
/// </summary>
|
||||
/// <returns>true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false</returns>
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
Marshal.FreeHGlobal(handle);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The status of the watermark flushing process and/or positive acknowledgment collection.
|
||||
/// </summary>
|
||||
public enum NormAckingStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The given sessionHandle is invalid or the given nodeId is not in the sender's acking list.
|
||||
/// </summary>
|
||||
NORM_ACK_INVALID,
|
||||
/// <summary>
|
||||
/// The positive acknowledgement collection process did not receive acknowledgment from every
|
||||
/// listed receiver (nodeId = NORM_NODE_ANY) or the identified nodeId did not respond.
|
||||
/// </summary>
|
||||
NORM_ACK_FAILURE,
|
||||
/// <summary>
|
||||
/// The flushing process at large has not yet completed (nodeId = NORM_NODE_ANY) or the given
|
||||
/// individual nodeId is still being queried for response.
|
||||
/// </summary>
|
||||
NORM_ACK_PENDING,
|
||||
/// <summary>
|
||||
/// All receivers (nodeId = NORM_NODE_ANY) responded with positive acknowledgement or the given
|
||||
/// specific nodeId did acknowledge.
|
||||
/// </summary>
|
||||
NORM_ACK_SUCCESS
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The type identifies the event with one of NORM protocol events.
|
||||
/// </summary>
|
||||
public enum NormEventType
|
||||
{
|
||||
/// <summary>
|
||||
/// This NormEventType indicates an invalid or "null" notification which should be ignored.
|
||||
/// </summary>
|
||||
NORM_EVENT_INVALID,
|
||||
/// <summary>
|
||||
/// This event indicates that there is room for additional transmit objects to be enqueued, or,
|
||||
/// if the handle of NORM_OBJECT_STREAM is given in the corresponding
|
||||
/// event "object" field, the application may successfully write to the indicated stream
|
||||
/// object. Note this event is not dispatched until a call to NormFileEnqueue(),
|
||||
/// NormDataEnqueue(), or NormStreamWrite() fails because of a filled transmit
|
||||
/// cache or stream buffer.
|
||||
/// </summary>
|
||||
NORM_TX_QUEUE_VACANCY,
|
||||
/// <summary>
|
||||
/// This event indicates the NORM protocol engine has no new data pending transmission
|
||||
/// and the application may enqueue additional objects for transmission.
|
||||
/// If the handle of a sender NORM_OBJECT_STREAM is given in the corresponding event
|
||||
/// "object" field, this indicates the stream transmit buffer has been emptied and the
|
||||
/// sender application may write to the stream (Use of NORM_TX_QUEUE_VACANCY may
|
||||
/// be preferred for this purpose since it allows the application to keep the NORM
|
||||
/// protocol engine busier sending data, resulting in higher throughput when attempting
|
||||
/// very high transfer rates).
|
||||
/// </summary>
|
||||
NORM_TX_QUEUE_EMPTY,
|
||||
/// <summary>
|
||||
/// This event indicates that the flushing process the NORM sender observes when
|
||||
/// it no longer has data ready for transmission has completed. The completion of the
|
||||
/// flushing process is a reasonable indicator (with a sufficient NORM "robust factor"
|
||||
/// value) that the receiver set no longer has any pending repair requests. Note the
|
||||
/// use of NORM's optional positive acknowledgement feature is more deterministic
|
||||
/// in this regards, but this notification is useful when there are non-acking (NACK-only)
|
||||
/// receivers. The default NORM robust factor of 20 (20 flush messages are
|
||||
/// sent at end-of-transmission) provides a high assurance of reliable transmission,
|
||||
/// even with packet loss rates of 50%.
|
||||
/// </summary>
|
||||
NORM_TX_FLUSH_COMPLETED,
|
||||
/// <summary>
|
||||
/// This event indicates that the flushing process initiated by a prior application call
|
||||
/// to NormSetWatermark() has completed. The posting of this event indicates the
|
||||
/// appropriate time for the application to make a call NormGetAckingStatus() to
|
||||
/// determine the results of the watermark flushing process.
|
||||
/// </summary>
|
||||
NORM_TX_WATERMARK_COMPLETED,
|
||||
/// <summary>
|
||||
/// This event indicates that an application-defined command previously enqueued
|
||||
/// with a call to NormSendCommand() has been transmitted, including any repetition.
|
||||
/// </summary>
|
||||
NORM_TX_CMD_SENT,
|
||||
/// <summary>
|
||||
/// This event indicates that the transport object referenced by the event's "object"
|
||||
/// field has completed at least one pass of total transmission. Note that this does not
|
||||
/// guarantee that reliable transmission has yet completed; only that the entire object
|
||||
/// content has been transmitted. Depending upon network behavior, several rounds
|
||||
/// of NACKing and repair transmissions may be required to complete reliable transfer.
|
||||
/// </summary>
|
||||
NORM_TX_OBJECT_SENT,
|
||||
/// <summary>
|
||||
/// This event indicates that the NORM protocol engine will no longer refer to the
|
||||
/// transport object identified by the event's "object" field. Typically, this will occur
|
||||
/// when the application has enqueued more objects than space available within the
|
||||
/// set sender transmit cache bounds. Posting of this notification means the application is
|
||||
/// free to free any resources (memory, files, etc) associated with the indicated "object".
|
||||
/// After this event, the given "object" handle (NormObjectHandle) is no longer valid unless
|
||||
/// it is specifically retained by the application.
|
||||
/// </summary>
|
||||
NORM_TX_OBJECT_PURGED,
|
||||
/// <summary>
|
||||
/// This event indicates that NORM Congestion Control operation has adjusted the
|
||||
/// transmission rate. The NormGetTxRate() call may be used to retrieve the new
|
||||
/// corresponding transmission rate. Note that if NormSetCongestionControl() was
|
||||
/// called with its adjustRate parameter set to false, then no actual rate change has
|
||||
/// occurred and the rate value returned by NormGetTxRate() reflects a "suggested"
|
||||
/// rate and not the actual transmission rate.
|
||||
/// </summary>
|
||||
NORM_TX_RATE_CHANGED,
|
||||
/// <summary>
|
||||
/// This event is posted when the NORM protocol engine completes the "graceful
|
||||
/// shutdown" of its participation as a sender in the indicated "session".
|
||||
/// </summary>
|
||||
NORM_LOCAL_SENDER_CLOSED,
|
||||
/// <summary>
|
||||
/// This event is posted when a receiver first receives messages from a specific remote
|
||||
/// NORM sender. This marks the beginning of the interval during which the application
|
||||
/// may reference the provided "node" handle (NormNodeHandle).
|
||||
/// </summary>
|
||||
NORM_REMOTE_SENDER_NEW,
|
||||
/// <summary>
|
||||
/// Remote sender instanceId or FEC params changed.
|
||||
/// </summary>
|
||||
NORM_REMOTE_SENDER_RESET,
|
||||
/// <summary>
|
||||
/// Remote sender src addr and/or port changed.
|
||||
/// </summary>
|
||||
NORM_REMOTE_SENDER_ADDRESS,
|
||||
/// <summary>
|
||||
/// This event is posted when a previously inactive (or new) remote sender is detected
|
||||
/// operating as an active sender within the session.
|
||||
/// </summary>
|
||||
NORM_REMOTE_SENDER_ACTIVE,
|
||||
/// <summary>
|
||||
/// This event is posted after a significant period of inactivity (no sender messages
|
||||
/// received) of a specific NORM sender within the session. The NORM protocol
|
||||
/// engine frees buffering resources allocated for this sender when it becomes inactive.
|
||||
/// </summary>
|
||||
NORM_REMOTE_SENDER_INACTIVE,
|
||||
/// <summary>
|
||||
/// This event is posted when the NORM protocol engine frees resources for, and
|
||||
/// thus invalidates the indicated "node" handle.
|
||||
/// </summary>
|
||||
NORM_REMOTE_SENDER_PURGED,
|
||||
/// <summary>
|
||||
/// This event indicates that an application-defined command has been received from
|
||||
/// a remote sender. The NormEvent node element indicates the NormNodeHandle
|
||||
/// value associated with the given sender. The NormNodeGetCommand() call can be
|
||||
/// used to retrieve the received command content.
|
||||
/// </summary>
|
||||
NORM_RX_CMD_NEW,
|
||||
/// <summary>
|
||||
/// This event is posted when reception of a new transport object begins and marks
|
||||
/// the beginning of the interval during which the specified "object" (NormObjectHandle)
|
||||
/// is valid.
|
||||
/// </summary>
|
||||
NORM_RX_OBJECT_NEW,
|
||||
/// <summary>
|
||||
/// This notification is posted when the NORM_INFO content for the indicated "object" is received.
|
||||
/// </summary>
|
||||
NORM_RX_OBJECT_INFO,
|
||||
/// <summary>
|
||||
/// This event indicates that the identified receive "object" has newly received data content.
|
||||
/// </summary>
|
||||
NORM_RX_OBJECT_UPDATED,
|
||||
/// <summary>
|
||||
/// This event is posted when a receive object is completely received, including
|
||||
/// available NORM_INFO content. Unless the application specifically retains the "object"
|
||||
/// handle, the indicated NormObjectHandle becomes invalid and must no longer be
|
||||
/// referenced.
|
||||
/// </summary>
|
||||
NORM_RX_OBJECT_COMPLETED,
|
||||
/// <summary>
|
||||
/// This notification is posted when a pending receive object's transmission is aborted
|
||||
/// by the remote sender. Unless the application specifically retains the "object"
|
||||
/// handle, the indicated NormObjectHandle becomes invalid and must no longer be
|
||||
/// referenced.
|
||||
/// </summary>
|
||||
NORM_RX_OBJECT_ABORTED,
|
||||
/// <summary>
|
||||
/// Upon receipt of app-extended watermark ack request.
|
||||
/// </summary>
|
||||
NORM_RX_ACK_REQUEST,
|
||||
/// <summary>
|
||||
/// This notification indicates that either the local sender estimate of GRTT has
|
||||
/// changed, or that a remote sender's estimate of GRTT has changed. The "sender"
|
||||
/// member of the NormEvent is set to NORM_NODE_INVALID if the local sender's
|
||||
/// GRTT estimate has changed or to the NormNodeHandle of the remote sender that
|
||||
/// has updated its estimate of GRTT
|
||||
/// </summary>
|
||||
NORM_GRTT_UPDATED,
|
||||
/// <summary>
|
||||
/// This event indicates that congestion control feedback from receivers has begun
|
||||
/// to be received (This also implies that receivers in the group are actually present
|
||||
/// and can be used as a cue to begin data transmission.). Note that congestion control
|
||||
/// must be enabled for this event to be posted.
|
||||
/// Congestion control feedback can be assumed to be received until a NORM_CC_INACTIVE event is posted.
|
||||
/// </summary>
|
||||
NORM_CC_ACTIVE,
|
||||
/// <summary>
|
||||
/// This event indicates there has been no recent congestion control feedback received
|
||||
/// from the receiver set and that the local NORM sender has reached its minimum
|
||||
/// transmit rate. Applications may wish to refrain from new data transmission until
|
||||
/// a NORM_CC_ACTIVE event is posted. This notification is only posted when congestion
|
||||
/// control operation is enabled and a previous NORM_CC_ACTIVE event has occurred.
|
||||
/// </summary>
|
||||
NORM_CC_INACTIVE,
|
||||
/// <summary>
|
||||
/// When NormSetAutoAcking.
|
||||
/// </summary>
|
||||
NORM_ACKING_NODE_NEW,
|
||||
/// <summary>
|
||||
/// ICMP error (e.g. destination unreachable).
|
||||
/// </summary>
|
||||
NORM_SEND_ERROR,
|
||||
/// <summary>
|
||||
/// Issues when timeout set by NormSetUserTimer() expires.
|
||||
/// </summary>
|
||||
NORM_USER_TIMEOUT
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The valid FEC Types.
|
||||
/// </summary>
|
||||
public enum NormFecType
|
||||
{
|
||||
/// <summary>
|
||||
/// Fully-specified, general purpose Reed-Solomon.
|
||||
/// </summary>
|
||||
RS,
|
||||
/// <summary>
|
||||
/// Fully-specified 8-bit Reed-Solmon per RFC 5510.
|
||||
/// </summary>
|
||||
RS8,
|
||||
/// <summary>
|
||||
/// Partially-specified "small block" codes.
|
||||
/// </summary>
|
||||
SB
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible flush modes.
|
||||
/// </summary>
|
||||
public enum NormFlushMode
|
||||
{
|
||||
/// <summary>
|
||||
/// No flushing occurs unless explicitly requested via NormStreamFlush().
|
||||
/// </summary>
|
||||
NORM_FLUSH_NONE,
|
||||
/// <summary>
|
||||
/// Causes NORM to immediately transmit all enqueued data for the stream (subject to session transmit rate limits),
|
||||
/// even if this results in NORM_DATA messages with "small" payloads.
|
||||
/// </summary>
|
||||
NORM_FLUSH_PASSIVE,
|
||||
/// <summary>
|
||||
/// The sender actively transmits NORM_CMD(FLUSH) messages after any enqueued stream content has been sent.
|
||||
/// </summary>
|
||||
NORM_FLUSH_ACTIVE
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The available nacking modes.
|
||||
/// </summary>
|
||||
public enum NormNackingMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not transmit any repair requests for the newly received object.
|
||||
/// </summary>
|
||||
NORM_NACK_NONE,
|
||||
/// <summary>
|
||||
/// Transmit repair requests for NORM_INFO content only as needed.
|
||||
/// </summary>
|
||||
NORM_NACK_INFO_ONLY,
|
||||
/// <summary>
|
||||
/// Transmit repair requests for entire object as needed.
|
||||
/// </summary>
|
||||
NORM_NACK_NORMAL
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible NORM data transport object types.
|
||||
/// </summary>
|
||||
public enum NormObjectType
|
||||
{
|
||||
/// <summary>
|
||||
/// A special NormObjectType value, NORM_OBJECT_NONE, indicates an invalid object type.
|
||||
/// </summary>
|
||||
NORM_OBJECT_NONE,
|
||||
/// <summary>
|
||||
/// A transport object of type NORM_OBJECT_DATA.
|
||||
/// </summary>
|
||||
NORM_OBJECT_DATA,
|
||||
/// <summary>
|
||||
/// A transport object of type NORM_OBJECT_FILE.
|
||||
/// </summary>
|
||||
NORM_OBJECT_FILE,
|
||||
/// <summary>
|
||||
/// A transport object of type NORM_OBJECT_STREAM.
|
||||
/// </summary>
|
||||
NORM_OBJECT_STREAM
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible probing modes.
|
||||
/// </summary>
|
||||
public enum NormProbingMode
|
||||
{
|
||||
/// <summary>
|
||||
/// The sender application must explicitly set its estimate of GRTT using the NormSetGrttEstimate() function.
|
||||
/// </summary>
|
||||
NORM_PROBE_NONE,
|
||||
/// <summary>
|
||||
/// The NORM sender still transmits NORM_CMD(CC) probe messages multiplexed with its data transmission,
|
||||
/// but the receiver set does not explicitly acknowledge these probes. Instead the receiver set is limited
|
||||
/// to opportunistically piggy-backing responses when NORM_NACK messages are generated.
|
||||
/// </summary>
|
||||
NORM_PROBE_PASSIVE,
|
||||
/// <summary>
|
||||
/// In this mode, the receiver set explicitly acknowledges NORM sender GRTT probes ((NORM_CMD(CC) messages)
|
||||
/// with NORM_ACK responses that are group-wise suppressed.
|
||||
/// </summary>
|
||||
NORM_PROBE_ACTIVE
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible for values for NORM repair boundary.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Customizes at what points the receiver initiates the NORM NACK repair process during protocol operation.
|
||||
/// </remarks>
|
||||
public enum NormRepairBoundary
|
||||
{
|
||||
/// <summary>
|
||||
/// For smaller block sizes, the NACK repair process is often/quickly initiated and the
|
||||
/// repair of an object will occur, as needed, during the transmission of the object.
|
||||
/// </summary>
|
||||
NORM_BOUNDARY_BLOCK,
|
||||
/// <summary>
|
||||
/// Causes the protocol to defer NACK process initiation until the current transport object
|
||||
/// has been completely transmitted.
|
||||
/// </summary>
|
||||
NORM_BOUNDARY_OBJECT
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
namespace Mil.Navy.Nrl.Norm.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible synchronization policies.
|
||||
/// </summary>
|
||||
public enum NormSyncPolicy
|
||||
{
|
||||
/// <summary>
|
||||
/// Attempt reception of "current" and new objects only (default).
|
||||
/// </summary>
|
||||
NORM_SYNC_CURRENT,
|
||||
/// <summary>
|
||||
/// Sync to current stream, but to beginning of stream.
|
||||
/// </summary>
|
||||
NORM_SYNC_STREAM,
|
||||
/// <summary>
|
||||
/// Attempt recovery and reliable reception of all objects
|
||||
/// held in sender transmit object cache and newer objects.
|
||||
/// </summary>
|
||||
NORM_SYNC_ALL
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace Mil.Navy.Nrl.Norm.IO
|
||||
{
|
||||
public interface INormEventListener
|
||||
{
|
||||
void NormEventOccurred(NormEvent normEvent);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Mil.Navy.Nrl.Norm.IO
|
||||
{
|
||||
public class NormInputStream : Stream
|
||||
{
|
||||
private NormInstance _normInstance;
|
||||
private NormSession _normSession;
|
||||
private NormStream? _normStream;
|
||||
|
||||
private List<INormEventListener> _normEventListeners;
|
||||
|
||||
private bool _closed;
|
||||
private object _closeLock;
|
||||
|
||||
private bool _bufferIsEmpty;
|
||||
private bool _receivedEof;
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
public NormInputStream(string address, int port)
|
||||
{
|
||||
// Create the NORM instance
|
||||
_normInstance = new NormInstance();
|
||||
|
||||
// Create the NORM session
|
||||
_normSession = _normInstance.CreateSession(address, port, NormNode.NORM_NODE_ANY);
|
||||
_normStream = null;
|
||||
|
||||
_normEventListeners = new List<INormEventListener>();
|
||||
|
||||
_closed = true;
|
||||
_closeLock = new object();
|
||||
|
||||
_bufferIsEmpty = true;
|
||||
_receivedEof = false;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void OpenDebugLog(string fileName)
|
||||
{
|
||||
if (fileName == null)
|
||||
{
|
||||
throw new IOException("File was name was not found.");
|
||||
}
|
||||
_normInstance.OpenDebugLog(fileName);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void CloseDebugLog() => _normInstance.CloseDebugLog();
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void NormSetDebugLevel(int level) { _normInstance.DebugLevel = level; }
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetMessageTrace(bool messageTrace) => _normSession.SetMessageTrace(messageTrace);
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetMulticastInterface(string multicastInterface)
|
||||
{
|
||||
_normSession.SetMulticastInterface(multicastInterface);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetEcnSupport(bool ecnEnable, bool ignoreLoss)
|
||||
{
|
||||
_normSession.SetEcnSupport(ecnEnable, ignoreLoss);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetTtl(byte ttl)
|
||||
{
|
||||
_normSession.SetTTL(ttl);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetTos(byte tos)
|
||||
{
|
||||
_normSession.SetTOS(tos);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void setSilentReceiver(bool silent, int maxDelay)
|
||||
{
|
||||
_normSession.SetSilentReceiver(silent, maxDelay);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetDefaultUnicastNack(bool defaultUnicastNack)
|
||||
{
|
||||
_normSession.SetDefaultUnicastNack(defaultUnicastNack);
|
||||
}
|
||||
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SeekMsgStart()
|
||||
{
|
||||
if (_normStream == null)
|
||||
{
|
||||
throw new InvalidOperationException("Can only seek msg start after the stream is connected");
|
||||
}
|
||||
|
||||
_normStream.SeekMsgStart();
|
||||
}
|
||||
|
||||
/// <param name="normEventListener">The INormEventListener to add.</param>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void AddNormEventListener(INormEventListener normEventListener)
|
||||
{
|
||||
lock (_normEventListeners)
|
||||
{
|
||||
_normEventListeners.Add(normEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
/// <param name="normEventListener">The INormEventListener to remove.</param>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void RemoveNormEventListener(INormEventListener normEventListener)
|
||||
{
|
||||
lock (_normEventListeners)
|
||||
{
|
||||
_normEventListeners.Remove(normEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
private void FireNormEventOccured(NormEvent normEvent)
|
||||
{
|
||||
lock (_normEventListeners)
|
||||
{
|
||||
foreach (var normEventListener in _normEventListeners)
|
||||
{
|
||||
normEventListener.NormEventOccurred(normEvent);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void Open(long bufferSpace)
|
||||
{
|
||||
lock (_closeLock)
|
||||
{
|
||||
if (!IsClosed)
|
||||
{
|
||||
throw new IOException("Stream is already open");
|
||||
}
|
||||
|
||||
_normSession.StartReceiver(bufferSpace);
|
||||
|
||||
_closed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
public override void Close()
|
||||
{
|
||||
lock (_closeLock)
|
||||
{
|
||||
if (IsClosed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_normStream?.Close(false);
|
||||
_normSession.StopSender();
|
||||
_normInstance.StopInstance();
|
||||
|
||||
_closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsClosed
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_closeLock)
|
||||
{
|
||||
return _closed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public int Read()
|
||||
{
|
||||
var buffer = new byte[1];
|
||||
|
||||
if (IsClosed)
|
||||
{
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
|
||||
if (Read(buffer) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (IsClosed)
|
||||
{
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
while (_bufferIsEmpty || _normInstance.HasNextEvent(0, 0))
|
||||
{
|
||||
ProcessEvent();
|
||||
|
||||
if (_receivedEof)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_normStream == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read from the stream
|
||||
if ((n = _normStream.Read(buffer, offset, count)) < 0)
|
||||
{
|
||||
throw new IOException("Break in stream integrity");
|
||||
}
|
||||
|
||||
_bufferIsEmpty = n == 0;
|
||||
}
|
||||
while (_bufferIsEmpty);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
private void ProcessEvent()
|
||||
{
|
||||
// Retrieve the next event
|
||||
var normEvent = _normInstance.GetNextEvent();
|
||||
|
||||
// Check if the stream was closed
|
||||
if (IsClosed)
|
||||
{
|
||||
throw new IOException("Stream closed");
|
||||
}
|
||||
|
||||
if (normEvent != null)
|
||||
{
|
||||
// Process the event
|
||||
var eventType = normEvent.Type;
|
||||
switch (eventType)
|
||||
{
|
||||
case NormEventType.NORM_RX_OBJECT_NEW:
|
||||
var normObject = normEvent.Object;
|
||||
if (normObject != null && normObject.Type == NormObjectType.NORM_OBJECT_STREAM)
|
||||
{
|
||||
_normStream = (NormStream)normObject;
|
||||
}
|
||||
break;
|
||||
|
||||
case NormEventType.NORM_RX_OBJECT_UPDATED:
|
||||
var theNormObject = normEvent.Object;
|
||||
if (theNormObject == null || !theNormObject.Equals(_normStream))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Signal that the buffer is not empty
|
||||
_bufferIsEmpty = false;
|
||||
break;
|
||||
|
||||
case NormEventType.NORM_RX_OBJECT_ABORTED:
|
||||
case NormEventType.NORM_RX_OBJECT_COMPLETED:
|
||||
_normStream = null;
|
||||
|
||||
// Signal that the stream has ended
|
||||
_receivedEof = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Notify listeners of the norm event
|
||||
FireNormEventOccured(normEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Mil.Navy.Nrl.Norm.IO
|
||||
{
|
||||
public class NormOutputStream : Stream
|
||||
{
|
||||
private NormInstance _normInstance;
|
||||
private NormSession _normSession;
|
||||
private NormStream? _normStream;
|
||||
|
||||
private List<INormEventListener> _normEventListeners;
|
||||
|
||||
private bool _closed;
|
||||
private object _closeLock;
|
||||
|
||||
private bool _bufferIsFull;
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
public NormOutputStream(string address, int port)
|
||||
{
|
||||
// Create the NORM instance
|
||||
_normInstance = new NormInstance();
|
||||
|
||||
// Create the NORM session
|
||||
_normSession = _normInstance.CreateSession(address, port, NormNode.NORM_NODE_ANY);
|
||||
|
||||
_normStream = null;
|
||||
|
||||
_normEventListeners = new List<INormEventListener>();
|
||||
|
||||
_closed = true;
|
||||
_closeLock = new object();
|
||||
|
||||
_bufferIsFull = false;
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void OpenDebugLog(string filename)
|
||||
{
|
||||
_normInstance.OpenDebugLog(filename);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void CloseDebugLog()
|
||||
{
|
||||
_normInstance.CloseDebugLog();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetDebugLevel(int level)
|
||||
{
|
||||
_normInstance.DebugLevel = level;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetMessageTrace(bool messageTrace)
|
||||
{
|
||||
_normSession.SetMessageTrace(messageTrace);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetMulticastInterface(string multicastInterface)
|
||||
{
|
||||
_normSession.SetMulticastInterface(multicastInterface);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetEcnSupport(bool ecnEnable, bool ignoreLoss)
|
||||
{
|
||||
_normSession.SetEcnSupport(ecnEnable, ignoreLoss);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetTtl(byte ttl)
|
||||
{
|
||||
_normSession.SetTTL(ttl);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetTos(byte tos)
|
||||
{
|
||||
_normSession.SetTOS(tos);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetCongestionControl(bool ccEnabled, bool ccAdjustRate)
|
||||
{
|
||||
_normSession.SetCongestionControl(ccEnabled, ccAdjustRate);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetTxRateBounds(double minTxRate, double maxTxRate)
|
||||
{
|
||||
_normSession.SetTxRateBounds(maxTxRate, minTxRate);
|
||||
}
|
||||
|
||||
public double TxRate
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return _normSession.TxRate;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_normSession.TxRate = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double GrttEstimate
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
return _normSession.GrttEstimate;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_normSession.GrttEstimate = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetGroupSize(long groupSize)
|
||||
{
|
||||
_normSession.SetGroupSize(groupSize);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetAutoParity(short autoParity)
|
||||
{
|
||||
_normSession.SetAutoParity(autoParity);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetBackoffFactor(double backoffFactor)
|
||||
{
|
||||
_normSession.SetBackoffFactor(backoffFactor);
|
||||
}
|
||||
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetAutoFlush(NormFlushMode flushMode)
|
||||
{
|
||||
if (_normStream == null)
|
||||
{
|
||||
throw new InvalidOperationException("Can only set auto flush after the stream is open");
|
||||
}
|
||||
_normStream.SetAutoFlush(flushMode);
|
||||
}
|
||||
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void SetPushEnable(bool pushEnable)
|
||||
{
|
||||
if (_normStream == null)
|
||||
{
|
||||
throw new InvalidOperationException("Can only set push enabled after the stream is open");
|
||||
}
|
||||
_normStream.SetPushEnable(pushEnable);
|
||||
}
|
||||
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void MarkEom()
|
||||
{
|
||||
if (_normStream == null)
|
||||
{
|
||||
throw new InvalidOperationException("Can only mark EOM after the stream is open");
|
||||
}
|
||||
_normStream.MarkEom();
|
||||
}
|
||||
|
||||
/// <param name="normEventListener">The INormEventListener to add.</param>
|
||||
public void AddNormEventListener(INormEventListener normEventListener)
|
||||
{
|
||||
lock (_normEventListeners)
|
||||
{
|
||||
_normEventListeners.Add(normEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
/// <param name="normEventListener">The INormEventListener to remove.</param>
|
||||
public void RemoveNormEventListener(INormEventListener normEventListener)
|
||||
{
|
||||
lock (_normEventListeners)
|
||||
{
|
||||
_normEventListeners.Remove(normEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void FireNormEventOccured(NormEvent normEvent)
|
||||
{
|
||||
lock (_normEventListeners)
|
||||
{
|
||||
foreach (var normEventListener in _normEventListeners)
|
||||
{
|
||||
normEventListener.NormEventOccurred(normEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
public void Open(int sessionId, long bufferSpace, int segmentSize, short blockSize, short numParity, long repairWindow)
|
||||
{
|
||||
lock (_closeLock)
|
||||
{
|
||||
if (IsClosed)
|
||||
{
|
||||
throw new IOException("Stream is already open");
|
||||
}
|
||||
|
||||
_normSession.StartSender(sessionId, bufferSpace, segmentSize, blockSize, numParity);
|
||||
|
||||
// Open the stream
|
||||
_normStream = _normSession.StreamOpen(repairWindow);
|
||||
|
||||
_closed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
public override void Close()
|
||||
{
|
||||
lock (_closeLock)
|
||||
{
|
||||
if (IsClosed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_normStream?.Close(false);
|
||||
_normSession.StopSender();
|
||||
_normInstance.StopInstance();
|
||||
|
||||
_closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsClosed
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_closeLock)
|
||||
{
|
||||
return _closed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void Write(int b)
|
||||
{
|
||||
if (IsClosed)
|
||||
{
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
|
||||
var buffer = new byte[1];
|
||||
buffer[0] = (byte)b;
|
||||
|
||||
Write(buffer);
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (IsClosed)
|
||||
{
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
while (_normInstance.HasNextEvent(0, 0))
|
||||
{
|
||||
ProcessEvent();
|
||||
}
|
||||
|
||||
// Wait while the buffer is full
|
||||
while (_bufferIsFull)
|
||||
{
|
||||
ProcessEvent();
|
||||
}
|
||||
|
||||
// Write some data
|
||||
if (_normStream == null || (n = _normStream.Write(buffer, offset, count)) < 0)
|
||||
{
|
||||
throw new IOException("Failed to write to stream");
|
||||
}
|
||||
|
||||
_bufferIsFull = n == 0;
|
||||
|
||||
count -= n;
|
||||
offset += n;
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IOException"></exception>
|
||||
private void ProcessEvent()
|
||||
{
|
||||
// Retrieve the next event
|
||||
var normEvent = _normInstance.GetNextEvent();
|
||||
|
||||
// Check if the stream was closed
|
||||
if (IsClosed)
|
||||
{
|
||||
throw new IOException("Stream closed");
|
||||
}
|
||||
|
||||
if (normEvent != null)
|
||||
{
|
||||
// Process the event
|
||||
var eventType = normEvent.Type;
|
||||
switch (eventType)
|
||||
{
|
||||
case NormEventType.NORM_TX_QUEUE_VACANCY:
|
||||
case NormEventType.NORM_TX_QUEUE_EMPTY:
|
||||
var normObject = normEvent.Object;
|
||||
if (normObject == null || !normObject.Equals(_normStream))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Signal that the buffer is not full
|
||||
_bufferIsFull = false;
|
||||
break;
|
||||
|
||||
case NormEventType.NORM_TX_OBJECT_SENT:
|
||||
case NormEventType.NORM_TX_OBJECT_PURGED:
|
||||
_normStream = null;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Notify listeners of the norm event
|
||||
FireNormEventOccured(normEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override bool CanRead => false;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override bool CanWrite => IsClosed;
|
||||
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace Mil.Navy.Nrl.Norm.IO
|
||||
{
|
||||
public class StreamBreakException : IOException
|
||||
{
|
||||
public StreamBreakException(string? message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,33 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mil.Navy.Nrl.Norm
|
||||
{
|
||||
/// <summary>
|
||||
/// A transport object of type NORM_OBJECT_DATA.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The data storage area for the specified transport object.
|
||||
/// </remarks>
|
||||
public class NormData : NormObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the data storage area associated with a transport object of type NORM_OBJECT_DATA.
|
||||
/// </summary>
|
||||
public byte[] GetData()
|
||||
{
|
||||
var dataPointer = NormDataAccessData(_handle);
|
||||
var length = NormObjectGetSize(_handle);
|
||||
var data = new byte[length];
|
||||
Marshal.Copy(dataPointer, data, 0, length);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor of NormData
|
||||
/// </summary>
|
||||
/// <param name="handle">Type is used to reference state kept for data transport objects being actively transmitted or received.</param>
|
||||
internal NormData(long handle) : base(handle)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
namespace Mil.Navy.Nrl.Norm
|
||||
{
|
||||
/// <summary>
|
||||
/// The NormEvent type is used to describe significant NORM protocol events.
|
||||
/// </summary>
|
||||
public class NormEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// The type identifies the event with one of NORM protocol events.
|
||||
/// </summary>
|
||||
private NormEventType _type { get; }
|
||||
/// <summary>
|
||||
/// Used to identify application in the NormSession.
|
||||
/// </summary>
|
||||
private long _sessionHandle { get; }
|
||||
/// <summary>
|
||||
/// This type is used to reference state kept by the NORM implementation with respect to other participants within a NormSession.
|
||||
/// </summary>
|
||||
private long _nodeHandle { get; }
|
||||
/// <summary>
|
||||
/// This type is used to reference state kept for data transport objects being actively transmitted or received.
|
||||
/// </summary>
|
||||
private long _objectHandle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Parameterized constructor of NormEvent
|
||||
/// </summary>
|
||||
/// <param name="type">indicates the NormEventType and determines how the other fields should be interpreted.</param>
|
||||
/// <param name="sessionHandle">indicates the applicable NormSessionHandle to which the event applies.</param>
|
||||
/// <param name="nodeHandle">indicates the applicable NormNodeHandle to which the event applies</param>
|
||||
/// <param name="objectHandle">indicates the applicable NormObjectHandle to which the event applies.</param>
|
||||
public NormEvent(NormEventType type, long sessionHandle, long nodeHandle, long objectHandle)
|
||||
{
|
||||
_type = type;
|
||||
_sessionHandle = sessionHandle;
|
||||
_nodeHandle = nodeHandle;
|
||||
_objectHandle = objectHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type identifies the event with one of NORM protocol events.
|
||||
/// </summary>
|
||||
public NormEventType Type => _type;
|
||||
|
||||
/// <summary>
|
||||
/// The NormSession associated with the event.
|
||||
/// </summary>
|
||||
public NormSession? Session
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_sessionHandle == NormSession.NORM_SESSION_INVALID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return NormSession.GetSession(_sessionHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A remote participant associated with the event.
|
||||
/// </summary>
|
||||
public NormNode? Node
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_nodeHandle == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new NormNode(_nodeHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// NORM transport object.
|
||||
/// </summary>
|
||||
public NormObject? Object
|
||||
{
|
||||
get
|
||||
{
|
||||
NormObject? normObject = null;
|
||||
var normObjectType = NormObjectGetType(_objectHandle);
|
||||
switch (normObjectType)
|
||||
{
|
||||
case NormObjectType.NORM_OBJECT_DATA:
|
||||
normObject = new NormData(_objectHandle);
|
||||
break;
|
||||
case NormObjectType.NORM_OBJECT_FILE:
|
||||
normObject = new NormFile(_objectHandle);
|
||||
break;
|
||||
case NormObjectType.NORM_OBJECT_STREAM:
|
||||
normObject= new NormStream(_objectHandle);
|
||||
break;
|
||||
case NormObjectType.NORM_OBJECT_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return normObject;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function returns a description of the NORM protocol event
|
||||
/// </summary>
|
||||
/// <returns>A string that includes the event type.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"NormEvent [type={_type}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
namespace Mil.Navy.Nrl.Norm
|
||||
{
|
||||
/// <summary>
|
||||
/// A transport object of type NORM_OBJECT_FILE.
|
||||
/// </summary>
|
||||
public class NormFile : NormObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Maximum length of file names.
|
||||
/// </summary>
|
||||
public const int FILENAME_MAX = 260;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor of NormFile
|
||||
/// </summary>
|
||||
/// <param name="handle">This type is used to reference state kept for data transport objects being actively transmitted or received.</param>
|
||||
internal NormFile(long handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the file.
|
||||
/// </summary>
|
||||
/// <exception cref="IOException">Thrown when failed to get file name.</exception>
|
||||
public unsafe string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
var buffer = stackalloc sbyte[FILENAME_MAX];
|
||||
|
||||
if (!NormFileGetName(_handle, buffer, FILENAME_MAX))
|
||||
{
|
||||
throw new IOException("Failed to get file name");
|
||||
}
|
||||
|
||||
return new string(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function renames the file used to store content for the NORM_OBJECT_FILE transport object.
|
||||
/// This allows receiver applications to rename (or move) received files as needed.
|
||||
/// NORM uses temporary file names for received files until the application explicitly renames the file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The full path of received file.</param>
|
||||
/// <exception cref="IOException">Thrown when failed to rename file.</exception>
|
||||
public void Rename(string filePath)
|
||||
{
|
||||
if(!NormFileRename(_handle, filePath))
|
||||
{
|
||||
throw new IOException("Failed to rename file");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
using Microsoft.Win32.SafeHandles;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Mil.Navy.Nrl.Norm
|
||||
{
|
||||
/// <summary>
|
||||
/// An instance of a NORM protocol engine
|
||||
/// </summary>
|
||||
public class NormInstance
|
||||
{
|
||||
/// <summary>
|
||||
/// Returned on error when getting the file descriptor for a NormInstance.
|
||||
/// </summary>
|
||||
public const int NORM_DESCRIPTOR_INVALID = 0;
|
||||
/// <summary>
|
||||
/// The _handle refers to the NORM protocol engine instance
|
||||
/// </summary>
|
||||
private long _handle;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for NormInstance with priority boost
|
||||
/// </summary>
|
||||
/// <param name="priorityBoost">The priorityBoost parameter, when set to a value of true, specifies that the NORM protocol engine thread be run with higher priority scheduling.</param>
|
||||
public NormInstance(bool priorityBoost)
|
||||
{
|
||||
CreateInstance(priorityBoost);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor for NormInstance
|
||||
/// </summary>
|
||||
public NormInstance() : this(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function creates an instance of a NORM protocol engine and is the necessary first step before any other API functions may be used.
|
||||
/// </summary>
|
||||
/// <param name="priorityBoost">The priorityBoost parameter, when set to a value of true, specifies that the NORM protocol engine thread be run with higher priority scheduling.</param>
|
||||
private void CreateInstance(bool priorityBoost)
|
||||
{
|
||||
var handle = NormCreateInstance(priorityBoost);
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The function immediately shuts down and destroys the NORM protocol engine instance referred to by the instanceHandle parameter.
|
||||
/// </summary>
|
||||
public void DestroyInstance()
|
||||
{
|
||||
NormDestroyInstance(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function creates a NORM protocol session (NormSession) using the address (multicast or unicast) and port
|
||||
/// parameters provided. While session state is allocated and initialized, active session participation does not begin
|
||||
/// until the session starts the sender and/or receiver to join the specified multicast group
|
||||
/// (if applicable) and start protocol operation.
|
||||
/// </summary>
|
||||
/// <param name="address">Specified address determines the destination of NORM messages sent </param>
|
||||
/// <param name="port">Valid, unused port number corresponding to the desired NORM session address. </param>
|
||||
/// <param name="localNodeId">Identifies the application's presence in the NormSession </param>
|
||||
/// <returns>The NormSession that was created</return
|
||||
/// <exception cref="IOException">Throws when fails to create session</exception>
|
||||
public NormSession CreateSession(string address, int port, long localNodeId)
|
||||
{
|
||||
var session = NormCreateSession(_handle, address, port, localNodeId);
|
||||
if (session == NormSession.NORM_SESSION_INVALID)
|
||||
{
|
||||
throw new IOException("Failed to create session");
|
||||
}
|
||||
return new NormSession(session);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the NORM protocol engine instance has a next event
|
||||
/// </summary>
|
||||
/// <param name="sec">The seconds to wait</param>
|
||||
/// <param name="usec">The microseconds to wait</param>
|
||||
/// <returns>True if the NORM protocol engine instance has a next event</returns>
|
||||
public bool HasNextEvent(int sec, int usec)
|
||||
{
|
||||
var totalMilliseconds = sec * 1000 + usec / 1000;
|
||||
var waitTime = TimeSpan.FromMilliseconds(totalMilliseconds);
|
||||
return HasNextEvent(waitTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the NORM protocol engine instance has a next event
|
||||
/// </summary>
|
||||
/// <param name="waitTime">The time to wait</param>
|
||||
/// <returns>True if the NORM protocol engine instance has a next event</returns>
|
||||
public bool HasNextEvent(TimeSpan waitTime)
|
||||
{
|
||||
var normDescriptor = NormGetDescriptor(_handle);
|
||||
if (normDescriptor == NORM_DESCRIPTOR_INVALID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
using var eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||
eventWaitHandle.SafeWaitHandle = new SafeWaitHandle(new IntPtr(normDescriptor), false);
|
||||
return eventWaitHandle.WaitOne(waitTime);
|
||||
}
|
||||
var hasNextEvent = false;
|
||||
var timeout = DateTime.Now.Add(waitTime);
|
||||
while (!hasNextEvent && DateTime.Now <= timeout)
|
||||
{
|
||||
using var socketHandle = new SafeSocketHandle(new IntPtr(normDescriptor), false);
|
||||
using var socket = new Socket(socketHandle);
|
||||
hasNextEvent = socket.Available > 0;
|
||||
}
|
||||
return hasNextEvent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function retrieves the next available NORM protocol event from the protocol engine.
|
||||
/// </summary>
|
||||
/// <param name="waitForEvent">waitForEvent specifies whether the call to this function is blocking or not, if "waitForEvent" is false, this is a non-blocking call. </param>
|
||||
/// <returns>Returns an instance of NormEvent if NormGetNextEvent() returns true, returns null otherwise. </returns>
|
||||
public NormEvent? GetNextEvent(bool waitForEvent)
|
||||
{
|
||||
bool success = NormGetNextEvent(_handle, out NormApi.NormEvent normEvent, waitForEvent);
|
||||
if (!success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new NormEvent(normEvent.Type, normEvent.Session, normEvent.Sender, normEvent.Object);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function retrieves the next available NORM protocol event from the protocol engine.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is an overload which calls GetNextEvent() with waitForEvent set as true.
|
||||
/// </remarks>
|
||||
/// <returns>Returns an instance of NormEvent if NormGetNextEvent() returns true, returns null otherwise.</returns>
|
||||
public NormEvent? GetNextEvent()
|
||||
{
|
||||
return GetNextEvent(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function sets the directory path used by receivers to cache newly-received NORM_OBJECT_FILE content.
|
||||
/// </summary>
|
||||
/// <param name="cachePath">the cachePath is a string specifying a valid (and writable) directory path.</param>
|
||||
/// <exception cref="IOException">Throws when fails to set the cache directory</exception>
|
||||
public void SetCacheDirectory(string cachePath)
|
||||
{
|
||||
if(!NormSetCacheDirectory(_handle, cachePath))
|
||||
{
|
||||
throw new IOException("Failed to set the cache directory");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function immediately stops the NORM protocol engine thread.
|
||||
/// </summary>
|
||||
public void StopInstance()
|
||||
{
|
||||
NormStopInstance(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function creates and starts an operating system thread to resume NORM protocol engine operation that was previously stopped by a call to StopInstance().
|
||||
/// </summary>
|
||||
/// <returns>Boolean as to the success of the instance restart. </return>
|
||||
public bool RestartInstance()
|
||||
{
|
||||
return NormRestartInstance(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immediately suspends the NORM protocol engine thread.
|
||||
/// </summary>
|
||||
/// <returns>Boolean as to the success of the instance suspension. </returns>
|
||||
public bool SuspendInstance()
|
||||
{
|
||||
return NormSuspendInstance(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows NORM debug output to be directed to a file instead of the default STDERR.
|
||||
/// </summary>
|
||||
public void ResumeInstance()
|
||||
{
|
||||
NormResumeInstance(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows NORM debug output to be directed to a file instead of the default STDERR.
|
||||
/// </summary>
|
||||
/// <param name="fileName">Full path and name of the debug log.</param>
|
||||
/// <exception cref="IOException">Throws when fails to open debug log"</exception>
|
||||
public void OpenDebugLog(string fileName)
|
||||
{
|
||||
if (!NormOpenDebugLog(_handle, fileName))
|
||||
{
|
||||
throw new IOException("Failed to open debug log");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function disables NORM debug output to be directed to a file instead of the default STDERR.
|
||||
/// </summary>
|
||||
public void CloseDebugLog()
|
||||
{
|
||||
NormCloseDebugLog(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows NORM debug output to be directed to a named pipe.
|
||||
/// </summary>
|
||||
/// <param name="pipename">The debug pipe name.</param>
|
||||
/// <exception cref="IOException">Throws when fails to open debug pipe.</exception>
|
||||
public void OpenDebugPipe(string pipename)
|
||||
{
|
||||
if (!NormOpenDebugPipe(_handle, pipename))
|
||||
{
|
||||
throw new IOException("Failed to open debug pipe");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The currently set debug level.
|
||||
/// </summary>
|
||||
public int DebugLevel
|
||||
{
|
||||
get => NormGetDebugLevel();
|
||||
set => NormSetDebugLevel(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
using System.Net;
|
||||
|
||||
namespace Mil.Navy.Nrl.Norm
|
||||
{
|
||||
/// <summary>
|
||||
/// A participant in a NORM protocol session
|
||||
/// </summary>
|
||||
public class NormNode
|
||||
{
|
||||
/// <summary>
|
||||
/// When creating a session, allows the NORM implementation to attempt to pick an identifier based on the host computer's "default" IP address.
|
||||
/// </summary>
|
||||
public const long NORM_NODE_ANY = 0xffffffff;
|
||||
/// <summary>
|
||||
/// The special value NORM_NODE_NONE corresponds to an invalid (or null) node.
|
||||
/// </summary>
|
||||
public const int NORM_NODE_NONE = 0;
|
||||
/// <summary>
|
||||
/// The special value NORM_NODE_INVALID corresponds to an invalid reference.
|
||||
/// </summary>
|
||||
public const int NORM_NODE_INVALID = 0;
|
||||
/// <summary>
|
||||
/// The handle is associated to the NORM protocol engine instance.
|
||||
/// </summary>
|
||||
private long _handle;
|
||||
|
||||
/// <summary>
|
||||
/// Parameterized contructor.
|
||||
/// </summary>
|
||||
/// <param name="handle">The handle is associated to the NORM protocol engine instance.</param>
|
||||
internal NormNode(long handle)
|
||||
{
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The NormNodeId identifier for the remote participant.
|
||||
/// </summary>
|
||||
public long Id => NormNodeGetId(_handle);
|
||||
|
||||
/// <summary>
|
||||
/// The current network source address detected for packets received from remote NORM sender.
|
||||
/// </summary>
|
||||
public unsafe IPEndPoint Address
|
||||
{
|
||||
get
|
||||
{
|
||||
var bufferLength = 256;
|
||||
var buffer = stackalloc byte[bufferLength];
|
||||
|
||||
if (!NormNodeGetAddress(_handle, buffer, ref bufferLength, out int port))
|
||||
{
|
||||
throw new IOException("Failed to get node address");
|
||||
}
|
||||
|
||||
var addressBytes = new ReadOnlySpan<byte>(buffer, bufferLength);
|
||||
var ipAddress = new IPAddress(addressBytes);
|
||||
return new IPEndPoint(ipAddress, port);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The advertised estimate of group round-trip timing (GRTT) for the remote sender.
|
||||
/// </summary>
|
||||
public double Grtt => NormNodeGetGrtt(_handle);
|
||||
|
||||
/// <summary>
|
||||
/// This function retrieves the content of an application-defined command that was received from a remote sender.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset or length are outside of the buffer.</exception>
|
||||
public int GetCommand(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (offset < 0 || offset >= buffer.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(offset), "The offset is out of range");
|
||||
}
|
||||
if (length < 1 || offset + length > buffer.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(length), "The length is out of range");
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* bufferPtr = buffer)
|
||||
{
|
||||
if (!NormNodeGetCommand(_handle, bufferPtr + offset, ref length))
|
||||
{
|
||||
throw new IOException("Failed to get command");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function controls the destination address of receiver feedback messages generated in response to a specific remote NORM sender.
|
||||
/// </summary>
|
||||
/// <param name="state">If state is true, "unicast NACKing" is enabled.</param>
|
||||
public void SetUnicastNack(bool state)
|
||||
{
|
||||
NormNodeSetUnicastNack(_handle, state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function sets the default "nacking mode" used for receiving new objects from a specific sender.
|
||||
/// </summary>
|
||||
/// <param name="nackingMode">Specifies the nacking mode.</param>
|
||||
public void SetNackingMode(NormNackingMode nackingMode)
|
||||
{
|
||||
NormNodeSetNackingMode(_handle, nackingMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows the receiver application to customize at what points the receiver initiates the NORM NACK repair process during protocol operation.
|
||||
/// </summary>
|
||||
/// <param name="repairBoundary">Specifies the repair boundary.</param>
|
||||
public void SetRepairBoundary(NormRepairBoundary repairBoundary)
|
||||
{
|
||||
NormNodeSetRepairBoundary(_handle, repairBoundary);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This routine sets the robustFactor as described in NormSetDefaultRxRobustFactor() for an individual remote sender.
|
||||
/// </summary>
|
||||
/// <param name="robustFactor">The robustFactor value determines how
|
||||
/// many times a NORM receiver will self-initiate NACKing (repair requests) upon cessation of packet reception from
|
||||
/// a sender. The default value is 20. Setting rxRobustFactor to -1 will make the NORM receiver infinitely persistent
|
||||
/// (i.e., it will continue to NACK indefinitely as long as it is missing data content).</param>
|
||||
public void SetRxRobustFactor(int robustFactor)
|
||||
{
|
||||
NormNodeSetRxRobustFactor(_handle, robustFactor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function releases memory resources that were allocated for a remote sender.
|
||||
/// </summary>
|
||||
public void FreeBuffers()
|
||||
{
|
||||
NormNodeFreeBuffers(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows the application to retain state associated even when the underlying NORM protocol engine might normally free the associated state.
|
||||
/// </summary>
|
||||
public void Retain()
|
||||
{
|
||||
NormNodeRetain(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function releases the Node so that the NORM protocol engine may free associated resources as needed.
|
||||
/// </summary>
|
||||
public void Release()
|
||||
{
|
||||
NormNodeRelease(_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
namespace Mil.Navy.Nrl.Norm
|
||||
{
|
||||
/// <summary>
|
||||
/// The base transport object.
|
||||
/// </summary>
|
||||
public class NormObject
|
||||
{
|
||||
/// <summary>
|
||||
/// The special value NORM_OBJECT_INVALID corresponds to an invalid reference.
|
||||
/// </summary>
|
||||
public const int NORM_OBJECT_INVALID = 0;
|
||||
/// <summary>
|
||||
/// Used to reference state kept for data transport objects being actively transmitted or received.
|
||||
/// </summary>
|
||||
protected long _handle;
|
||||
|
||||
/// <summary>
|
||||
/// Internal constructor for NormObject
|
||||
/// </summary>
|
||||
/// <param name="handle">Identifies an instance of NormObject</param>
|
||||
internal NormObject(long handle)
|
||||
{
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to reference state kept for data transport objects being actively transmitted or received.
|
||||
/// </summary>
|
||||
public long Handle => _handle;
|
||||
|
||||
/// <summary>
|
||||
/// Data associated with NormObject.
|
||||
/// </summary>
|
||||
public byte[]? Info
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!NormObjectHasInfo(_handle))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var length = NormObjectGetInfoLength(_handle);
|
||||
var buffer = new byte[length];
|
||||
NormObjectGetInfo(_handle, buffer, length);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type of Norm object.
|
||||
/// Valid types include:
|
||||
/// NORM_OBJECT_FILE
|
||||
/// NORM_OBJECT_DATA
|
||||
/// NORM_OBJECT_STREAM
|
||||
/// </summary>
|
||||
public NormObjectType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return NormObjectGetType(_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The size (in bytes) of the transport object.
|
||||
/// </summary>
|
||||
public long Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return NormObjectGetSize(_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The NormNodeHandle corresponding to the remote sender of the transport object.
|
||||
/// </summary>
|
||||
/// <exception cref="IOException">Thrown when NormObjectGetSender() returns NORM_NODE_INVALID, indicating locally originated sender object.</exception>
|
||||
public long Sender
|
||||
{
|
||||
get
|
||||
{
|
||||
var sender = NormObjectGetSender(_handle);
|
||||
if(sender == NormNode.NORM_NODE_INVALID)
|
||||
{
|
||||
throw new IOException("Locally originated sender object");
|
||||
}
|
||||
return sender;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function sets the "nacking mode" used for receiving a specific transport object.
|
||||
/// </summary>
|
||||
/// <param name="nackingMode">Specifies the nacking mode.</param>
|
||||
public void SetNackingMode(NormNackingMode nackingMode)
|
||||
{
|
||||
NormObjectSetNackingMode(_handle, nackingMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function can be used to determine the progress of reception of the NORM transport object
|
||||
/// </summary>
|
||||
/// <returns>A number of object source data bytes pending reception (or transmission) is returned.</returns>
|
||||
public long GetBytesPending()
|
||||
{
|
||||
return NormObjectGetBytesPending(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function immediately cancels the transmission of a local sender transport object or the reception of a specified
|
||||
/// object from a remote sender.
|
||||
/// </summary>
|
||||
public void Cancel()
|
||||
{
|
||||
NormObjectCancel(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function "retains" the objectHandle and any state associated with it for further use by the application even
|
||||
/// when the NORM protocol engine may no longer require access to the associated transport object.
|
||||
/// </summary>
|
||||
public void Retain()
|
||||
{
|
||||
NormObjectRetain(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function complements the Retain() call by immediately freeing any resources associated with
|
||||
/// the given objectHandle, assuming the underlying NORM protocol engine no longer requires access to the corresponding
|
||||
/// transport object. Note the NORM protocol engine retains/releases state for associated objects for its own
|
||||
/// needs and thus it is very unsafe for an application to call Release() for an objectHandle for which
|
||||
/// it has not previously explicitly retained via Retain().
|
||||
/// </summary>
|
||||
public void Release()
|
||||
{
|
||||
NormObjectRelease(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash code of the object.
|
||||
/// </summary>
|
||||
/// <returns>Returns the handle of the object.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int)_handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decides wether specified object is equal another.
|
||||
/// </summary>
|
||||
/// <param name="obj">NormObject to compare to.</param>
|
||||
/// <returns>Returns true if two objects equal, false otherwise.</returns>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if(obj is NormObject)
|
||||
{
|
||||
return _handle == ((NormObject)obj).Handle;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,205 @@
|
|||
namespace Mil.Navy.Nrl.Norm
|
||||
{
|
||||
/// <summary>
|
||||
/// A transport object of type NORM_OBJECT_STREAM.
|
||||
/// </summary>
|
||||
public class NormStream : NormObject
|
||||
{
|
||||
/// <summary>
|
||||
/// This boolean tells whether the transmit stream, specified by the streamHandle parameter,
|
||||
/// has buffer space available so that the application may successfully make a call to NormStreamWrite().
|
||||
/// </summary>
|
||||
public bool HasVacancy
|
||||
{
|
||||
get
|
||||
{
|
||||
return NormStreamHasVacancy(_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current read offset value for the receive stream.
|
||||
/// </summary>
|
||||
public long ReadOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return NormStreamGetReadOffset(_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal constructor for NormStream
|
||||
/// </summary>
|
||||
/// <param name="handle">The handle is associated to the NORM protocol engine instance</param>
|
||||
internal NormStream(long handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function enqueues data for transmission within the NORM stream.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The buffer parameter must be a pointer to the data to be enqueued.</param>
|
||||
/// <param name="offset">The offset indicated where in the buffer to start writing the data.
|
||||
/// Note: If the data is written in its entirety, offset should be set to 0.</param>
|
||||
/// <param name="length">The length parameter indicates the length of the data content.</param>
|
||||
/// <returns>This function returns the number of bytes of data successfully enqueued for NORM stream transmission.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset or length are outside of the buffer.</exception>
|
||||
public int Write(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (offset < 0 || offset >= buffer.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(offset), "The offset is out of range");
|
||||
}
|
||||
if (length < 1 || offset + length > buffer.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(length), "The length is out of range");
|
||||
}
|
||||
|
||||
int numBytes;
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* bufferPtr = buffer)
|
||||
{
|
||||
numBytes = NormStreamWrite(_handle, bufferPtr + offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function allows the application to indicate to the NORM protocol engine that the last data successfully written
|
||||
/// to the stream indicated by streamHandle corresponded to the end of an application-defined message boundary.
|
||||
/// </summary>
|
||||
public void MarkEom()
|
||||
{
|
||||
NormStreamMarkEom(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function causes an immediate "flush" of the transmit stream.
|
||||
/// </summary>
|
||||
/// <param name="eom">The optional eom parameter, when set to true, allows the sender application to mark an end-of-message indication
|
||||
/// (see NormStreamMarkEom()) for the stream and initiate flushing in a single function call.</param>
|
||||
/// <param name="flushMode">The default stream "flush" operation invoked via
|
||||
/// NormStreamFlush() for flushMode equal to NORM_FLUSH_PASSIVE causes NORM to immediately transmit all
|
||||
/// enqueued data for the stream(subject to session transmit rate limits), even if this results in NORM_DATA messages
|
||||
/// with "small" payloads.If the optional flushMode parameter is set to NORM_FLUSH_ACTIVE, the application can
|
||||
/// achieve reliable delivery of stream content up to the current write position in an even more proactive fashion.In
|
||||
/// this case, the sender additionally, actively transmits NORM_CMD(FLUSH) messages after any enqueued stream
|
||||
/// content has been sent. This immediately prompt receivers for repair requests which reduces latency of reliable
|
||||
/// delivery, but at a cost of some additional messaging. Note any such "active" flush activity will be terminated upon
|
||||
/// the next subsequent write to the stream.If flushMode is set to NORM_FLUSH_NONE, this call has no effect other than
|
||||
/// the optional end-of-message marking described here. </param>
|
||||
public void Flush(bool eom, NormFlushMode flushMode)
|
||||
{
|
||||
NormStreamFlush(_handle, eom, flushMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function causes an immediate "flush" of the transmit stream.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is an overload which calls Flush() with eom set as false and flushMode set to NORM_FLUSH_PASSIVE
|
||||
/// </remarks>
|
||||
public void Flush()
|
||||
{
|
||||
Flush(false, NormFlushMode.NORM_FLUSH_PASSIVE);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function halts transfer of the stream and releases any resources used unless the associated object
|
||||
/// has been explicitly retained by a call to NormObjectRetain().
|
||||
/// </summary>
|
||||
/// <param name="graceful">The optional graceful parameter, when
|
||||
/// set to a value of true, may be used by NORM senders to initiate "graceful" shutdown of a transmit stream.</param>
|
||||
public void Close(bool graceful)
|
||||
{
|
||||
NormStreamClose(_handle, graceful);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function halts transfer of the stream and releases any resources used unless the associated object
|
||||
/// has been explicitly retained by a call to NormObjectRetain().
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is an overload which calls Close() with graceful set as false.
|
||||
/// </remarks>
|
||||
public void Close()
|
||||
{
|
||||
Close(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function can be used by the receiver application to read any available data from an incoming NORM stream.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The buffer parameter must be a pointer to an array where the received
|
||||
/// data can be stored of a length as referenced by the length parameter. </param>
|
||||
/// <param name="offset">Indicates where in the buffer to start reading the data.
|
||||
/// Note: To read the data in its entirety, begin at offset 0.</param>
|
||||
/// <param name="length">Expected length of data received</param>
|
||||
/// <returns>The length of data received</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the offset or length are outside of the buffer.</exception>
|
||||
public int Read(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (offset < 0 || offset >= buffer.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(offset), "The offset is out of range");
|
||||
}
|
||||
if (length < 1 || offset + length > buffer.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(length), "The length is out of range");
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* bufferPtr = buffer)
|
||||
{
|
||||
if (!NormStreamRead(_handle, bufferPtr + offset, ref length))
|
||||
{
|
||||
length = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function advances the read offset of the receive stream referenced by the streamHandle parameter to align
|
||||
/// with the next available message boundary
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// This function returns a value of true when start-of-message is found. The next call to NormStreamRead() will
|
||||
/// retrieve data aligned with the message start. If no new message boundary is found in the buffered receive data for
|
||||
/// the stream, the function returns a value of false. In this case, the application should defer repeating a call to this
|
||||
/// function until a subsequent NORM_RX_OBJECT_UPDATE notification is posted.</returns>
|
||||
public bool SeekMsgStart()
|
||||
{
|
||||
return NormStreamSeekMsgStart(_handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function controls how the NORM API behaves when the application attempts to enqueue new stream data for transmission
|
||||
/// when the associated stream's transmit buffer is fully occupied with data pending original or repair transmission.
|
||||
/// </summary>
|
||||
/// <param name="pushEnable"> By default (pushEnable = false), a call to NormStreamWrite() will return a zero value under this
|
||||
/// condition, indicating it was unable to enqueue the new data. However, if pushEnable is set to true for a given
|
||||
/// streamHandle, the NORM protocol engine will discard the oldest buffered stream data(even if it is pending repair
|
||||
/// transmission or has never been transmitted) as needed to enqueue the new data.</param>
|
||||
public void SetPushEnable(bool pushEnable)
|
||||
{
|
||||
NormStreamSetPushEnable(_handle, pushEnable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function sets "automated flushing" for the NORM transmit stream indicated by the streamHandle parameter.
|
||||
/// </summary>
|
||||
/// <param name="flushMode">Possible values for the flushMode parameter include NORM_FLUSH_NONE, NORM_FLUSH_PASSIVE, and NORM_FLUSH_ACTIVE.</param>
|
||||
public void SetAutoFlush(NormFlushMode flushMode)
|
||||
{
|
||||
NormStreamSetAutoFlush(_handle, flushMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
global using static Mil.Navy.Nrl.Norm.NormApi;
|
||||
global using NormEvent = Mil.Navy.Nrl.Norm.NormEvent;
|
||||
global using Mil.Navy.Nrl.Norm.Enums;
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bogus" Version="34.0.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="3.2.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Mil.Navy.Nrl.Norm\Mil.Navy.Nrl.Norm.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="copy ..\..\..\..\build\norm*.dll $(TargetDir)
cd $(TargetDir)
del /f norm.dll
ren norm*.dll norm.dll" Condition="'$(OS)' == 'Windows_NT'" />
|
||||
<Exec Command="cp -f ../../../../build/libnorm.so $(TargetDir)norm.so" Condition="'$(OS)' != 'Windows_NT'" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
using Bogus;
|
||||
using Mil.Navy.Nrl.Norm.Buffers;
|
||||
using System.Text;
|
||||
|
||||
namespace Mil.Navy.Nrl.Norm.IntegrationTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests for NORM instance
|
||||
/// </summary>
|
||||
public class NormInstanceTests : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The NORM instance
|
||||
/// </summary>
|
||||
private NormInstance _normInstance;
|
||||
private NormSession? _normSession;
|
||||
/// <summary>
|
||||
/// Determines if the NORM instance has been destroyed
|
||||
/// </summary>
|
||||
private bool _isDestroyed;
|
||||
|
||||
private string _testPath;
|
||||
|
||||
private void CreateTestDirectory()
|
||||
{
|
||||
if (!Directory.Exists(_testPath))
|
||||
{
|
||||
Directory.CreateDirectory(_testPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteTestDirectory()
|
||||
{
|
||||
if (Directory.Exists(_testPath))
|
||||
{
|
||||
Directory.Delete(_testPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor for NORM instance tests
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Creates the NORM instance.
|
||||
/// Initializes _isDestroyed to false.
|
||||
/// </remarks>
|
||||
public NormInstanceTests()
|
||||
{
|
||||
_normInstance = new NormInstance();
|
||||
_isDestroyed = false;
|
||||
var currentDirectory = Directory.GetCurrentDirectory();
|
||||
_testPath = Path.Combine(currentDirectory, Guid.NewGuid().ToString());
|
||||
CreateTestDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroy the NORM instance
|
||||
/// </summary>
|
||||
private void DestroyInstance()
|
||||
{
|
||||
if (!_isDestroyed)
|
||||
{
|
||||
_normSession?.DestroySession();
|
||||
_normInstance.CloseDebugLog();
|
||||
_normInstance.DestroyInstance();
|
||||
_isDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose destroys the NORM instance
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
DestroyInstance();
|
||||
DeleteTestDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for creating a NORM instance
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreatesNormInstance()
|
||||
{
|
||||
Assert.NotNull(_normInstance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for creating a NORM instance
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreatesNormInstanceWithPriorityBoost()
|
||||
{
|
||||
_normInstance.DestroyInstance();
|
||||
_normInstance = new NormInstance(true);
|
||||
Assert.NotNull(_normInstance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for destroying a NORM instance
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void DestroysNormInstance()
|
||||
{
|
||||
DestroyInstance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for creating a NORM session
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreatesSession()
|
||||
{
|
||||
var faker = new Faker();
|
||||
var sessionAddress = "224.1.2.3";
|
||||
var sessionPort = faker.Internet.Port();
|
||||
var localNodeId = NormNode.NORM_NODE_ANY;
|
||||
|
||||
_normSession = _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId);
|
||||
Assert.NotNull(_normSession);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for throwing an exception when attempting to create a NORM session with an invalid session address
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CreateSessionThrowsExceptionForInvalidSessionAddress()
|
||||
{
|
||||
var sessionAddress = "999.999.999.999";
|
||||
var sessionPort = 6003;
|
||||
var localNodeId = NormNode.NORM_NODE_ANY;
|
||||
|
||||
Assert.Throws<IOException>(() => _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StopInstance()
|
||||
{
|
||||
var sessionAddress = "224.1.2.3";
|
||||
var sessionPort = 6003;
|
||||
var localNodeId = NormNode.NORM_NODE_ANY;
|
||||
|
||||
_normSession = _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId);
|
||||
|
||||
_normInstance.StopInstance();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RestartInstance()
|
||||
{
|
||||
var sessionAddress = "224.1.2.3";
|
||||
var sessionPort = 6003;
|
||||
var localNodeId = NormNode.NORM_NODE_ANY;
|
||||
var expected = true;
|
||||
_normSession = _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId);
|
||||
|
||||
_normInstance.StopInstance();
|
||||
|
||||
var actual = _normInstance.RestartInstance();
|
||||
Assert.Equal(expected,actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SuspendInstance()
|
||||
{
|
||||
var sessionAddress = "224.1.2.3";
|
||||
var sessionPort = 6003;
|
||||
var localNodeId = NormNode.NORM_NODE_ANY;
|
||||
var expected = true;
|
||||
_normSession = _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId);
|
||||
|
||||
_normInstance.StopInstance();
|
||||
|
||||
var actual = _normInstance.SuspendInstance();
|
||||
Assert.Equal(expected,actual);
|
||||
}
|
||||
[Fact]
|
||||
public void ResumeInstance()
|
||||
{
|
||||
var sessionAddress = "224.1.2.3";
|
||||
var sessionPort = 6003;
|
||||
var localNodeId = NormNode.NORM_NODE_ANY;
|
||||
_normSession = _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId);
|
||||
|
||||
_normInstance.StopInstance();
|
||||
|
||||
_normInstance.ResumeInstance();
|
||||
Assert.NotNull(_normInstance);
|
||||
}
|
||||
[Fact]
|
||||
public void OpenDebugLog(){
|
||||
var fileName = Guid.NewGuid().ToString();
|
||||
var filePath = Path.Combine(_testPath, fileName);
|
||||
|
||||
_normInstance.OpenDebugLog(filePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloseDebugLog()
|
||||
{
|
||||
_normInstance.CloseDebugLog();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OpensDebugPipe()
|
||||
{
|
||||
var pipename = "test.pipe";
|
||||
Assert.Throws<IOException>(() => _normInstance.OpenDebugPipe(pipename));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetsDebugLevel()
|
||||
{
|
||||
var expectedDebugLevel = 12;
|
||||
_normInstance.DebugLevel = expectedDebugLevel;
|
||||
var actualDebugLevel = _normInstance.DebugLevel;
|
||||
Assert.Equal(expectedDebugLevel, actualDebugLevel);
|
||||
}
|
||||
|
||||
[SkippableFact(typeof(IOException))]
|
||||
public void HasEventsFromTimeSpan()
|
||||
{
|
||||
var faker = new Faker();
|
||||
var sessionAddress = "224.1.2.3";
|
||||
var sessionPort = faker.Internet.Port();
|
||||
var localNodeId = NormNode.NORM_NODE_ANY;
|
||||
|
||||
_normSession = _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId);
|
||||
|
||||
_normSession.StartSender(1024 * 1024, 1400, 64, 16);
|
||||
|
||||
var dataContent = faker.Lorem.Paragraph();
|
||||
var data = Encoding.ASCII.GetBytes(dataContent);
|
||||
using var dataBuffer = ByteBuffer.AllocateDirect(data.Length);
|
||||
dataBuffer.WriteArray(0, data, 0, data.Length);
|
||||
_normSession.DataEnqueue(dataBuffer, 0, data.Length);
|
||||
|
||||
Assert.True(_normInstance.HasNextEvent(TimeSpan.FromSeconds(1.5)));
|
||||
|
||||
_normSession.StopSender();
|
||||
}
|
||||
|
||||
[SkippableFact(typeof(IOException))]
|
||||
public void HasEventsFromSecondsAndMicroseconds()
|
||||
{
|
||||
var faker = new Faker();
|
||||
var sessionAddress = "224.1.2.3";
|
||||
var sessionPort = faker.Internet.Port();
|
||||
var localNodeId = NormNode.NORM_NODE_ANY;
|
||||
|
||||
_normSession = _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId);
|
||||
|
||||
_normSession.StartSender(1024 * 1024, 1400, 64, 16);
|
||||
|
||||
var dataContent = faker.Lorem.Paragraph();
|
||||
var data = Encoding.ASCII.GetBytes(dataContent);
|
||||
using var dataBuffer = ByteBuffer.AllocateDirect(data.Length);
|
||||
dataBuffer.WriteArray(0, data, 0, data.Length);
|
||||
_normSession.DataEnqueue(dataBuffer, 0, data.Length);
|
||||
|
||||
Assert.True(_normInstance.HasNextEvent(1, 500000));
|
||||
|
||||
_normSession.StopSender();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1 @@
|
|||
global using Xunit;
|
||||
Loading…
Reference in New Issue