.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
|
*.o
|
||||||
*.a
|
*.a
|
||||||
|
|
||||||
|
# build java files
|
||||||
|
*.class
|
||||||
|
|
||||||
|
#build android files
|
||||||
|
android/.gradle
|
||||||
|
|
||||||
# waf cruft
|
# waf cruft
|
||||||
.waf*
|
.waf*
|
||||||
.lock-waf*
|
.lock-waf*
|
||||||
|
waf*/*
|
||||||
|
|
||||||
# OS generated files #
|
# OS generated files #
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
@ -30,3 +37,275 @@ norp/makefiles/norp
|
||||||
.Trashes
|
.Trashes
|
||||||
ehthumbs.db
|
ehthumbs.db
|
||||||
Thumbs.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