.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>pull/85/head
parent
3a20a8bcb2
commit
26944463e2
|
|
@ -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,272 @@ 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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
.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
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.4.33213.308
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "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("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "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
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|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
|
||||||
|
{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
|
||||||
|
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}
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {8BC1F27F-D633-4B45-A16D-D112CB08840E}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@startuml
|
@startuml
|
||||||
enum NormNackingMode {
|
enum NormNackingMode {
|
||||||
ORM_NACK_NONE
|
NORM_NACK_NONE
|
||||||
NORM_NACK_INFO_ONLY
|
NORM_NACK_INFO_ONLY
|
||||||
NORM_NACK_NORMAL
|
NORM_NACK_NORMAL
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,15 @@ class NormInputStream {
|
||||||
+ Read() : int
|
+ Read() : int
|
||||||
+ <<override>> Read(buffer:byte[], offset:int, length:int) : int
|
+ <<override>> Read(buffer:byte[], offset:int, length:int) : int
|
||||||
- ProcessEvent() : void
|
- 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>>
|
||||||
}
|
}
|
||||||
Stream <|-- NormInputStream
|
Stream <|-- NormInputStream
|
||||||
@enduml
|
@enduml
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class NormOutputStream {
|
||||||
+ SetTtl(ttl:byte) : void
|
+ SetTtl(ttl:byte) : void
|
||||||
+ SetTos(tos:byte) : void
|
+ SetTos(tos:byte) : void
|
||||||
+ SetCongestionControl(ccEnabled:bool, ccAdjustRate: bool) : void
|
+ SetCongestionControl(ccEnabled:bool, ccAdjustRate: bool) : void
|
||||||
+ SetTxRateBounds(rateMin:double, rateMax:double) : void
|
+ SetTxRateBounds(minTxRate:double, maxTxRate:double) : void
|
||||||
+ TxRate:double <<get>> <<set>>
|
+ TxRate:double <<get>> <<set>>
|
||||||
+ GrttEstimate:double <<get>> <<set>>
|
+ GrttEstimate:double <<get>> <<set>>
|
||||||
+ SetGroupSize(groupSize:long) : void
|
+ SetGroupSize(groupSize:long) : void
|
||||||
|
|
@ -30,11 +30,20 @@ class NormOutputStream {
|
||||||
+ RemoveNormEventListener(normEventListener:INormEventListener): void
|
+ RemoveNormEventListener(normEventListener:INormEventListener): void
|
||||||
- FireNormEventOccured(normEvent:NormEvent) : void
|
- FireNormEventOccured(normEvent:NormEvent) : void
|
||||||
+ Open(sessionId:int, bufferSpace:long, segmentSize:int, blockSize:short, numParity:short, repairWindow:long) : void
|
+ Open(sessionId:int, bufferSpace:long, segmentSize:int, blockSize:short, numParity:short, repairWindow:long) : void
|
||||||
+ <<override>> Dispose() : void
|
+ <<override>> Close() : void
|
||||||
+ IsClosed : bool <<get>>
|
+ IsClosed : bool <<get>>
|
||||||
+ Write(b:int) : void
|
+ Write(b:int) : void
|
||||||
+ <<override>> Write(buffer:byte[], offset:int, count:int)
|
+ <<override>> Write(buffer:byte[], offset:int, count:int)
|
||||||
- ProcessEvent() : void
|
- ProcessEvent() : void
|
||||||
|
+ <<override>> Flush() : void
|
||||||
|
+ <<override>> Read(buffer:byte[], offset:int, length: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>>
|
||||||
}
|
}
|
||||||
Stream <|-- NormOutputStream
|
Stream <|-- NormOutputStream
|
||||||
@enduml
|
@enduml
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
@startuml
|
@startuml
|
||||||
|
struct NormEvent
|
||||||
|
{
|
||||||
|
+ Type : NormEventType
|
||||||
|
+ Session : long
|
||||||
|
+ Sender : long
|
||||||
|
+ Object : long
|
||||||
|
}
|
||||||
class NormApi
|
class NormApi
|
||||||
{
|
{
|
||||||
+ <<const>> NORM_OBJECT_INVALID : int = 0
|
|
||||||
+ <<const>> FILENAME_MAX : int = 260
|
|
||||||
+ <<const>> NORM_LIBRARY : string = "norm"
|
+ <<const>> NORM_LIBRARY : string = "norm"
|
||||||
+ {static} NormGetVersion(major:int, minor:int, patch:int) : int
|
|
||||||
+ {static} NormCreateInstance() : long
|
|
||||||
+ {static} NormCreateInstance(priorityBoost:bool) : long
|
+ {static} NormCreateInstance(priorityBoost:bool) : long
|
||||||
+ {static} NormDestroyInstance(instanceHandle:long) : void
|
+ {static} NormDestroyInstance(instanceHandle:long) : void
|
||||||
+ {static} NormStopInstance(instanceHandle:long) : void
|
+ {static} NormStopInstance(instanceHandle:long) : void
|
||||||
|
|
@ -13,63 +16,36 @@ class NormApi
|
||||||
+ {static} NormSuspendInstance(instanceHandle:long) : bool
|
+ {static} NormSuspendInstance(instanceHandle:long) : bool
|
||||||
+ {static} NormResumeInstance(instanceHandle:long) : void
|
+ {static} NormResumeInstance(instanceHandle:long) : void
|
||||||
+ {static} NormSetCacheDirectory(instanceHandle:long, cachePath:string) : bool
|
+ {static} NormSetCacheDirectory(instanceHandle:long, cachePath:string) : bool
|
||||||
+ {static} NormGetNextEvent(instanceHandle:long, theEvent:NormEvent) : bool
|
|
||||||
+ {static} NormGetNextEvent(instanceHandle:long, theEvent:NormEvent, waitForEvent:bool) : bool
|
+ {static} NormGetNextEvent(instanceHandle:long, theEvent:NormEvent, waitForEvent:bool) : bool
|
||||||
+ {static} NormGetDescriptor(instanceHandle:long) : NormDescriptor
|
+ {static} NormGetDescriptor(instanceHandle:long) : int
|
||||||
+ {static} NormCreateSession(instanceHandle:long, sessionAddress:string, sessionPort:int, localNodeId:long) : long
|
+ {static} NormCreateSession(instanceHandle:long, sessionAddress:string, sessionPort:int, localNodeId:long) : long
|
||||||
+ {static} NormDestroySession(sessionHandle:long) : void
|
+ {static} NormDestroySession(sessionHandle:long) : void
|
||||||
+ {static} NormGetInstance(sessionHandle:long) : long
|
|
||||||
+ {static} NormIsUnicastAddress(address:string) : bool
|
|
||||||
+ {static} NormSetUserTimer(sessionHandle:long, seconds:double) : void
|
|
||||||
+ {static} NormCancelUserTimer(sessionHandle:long) : void
|
|
||||||
+ {static} NormGetLocalNodeId(sessionHandle:long) : long
|
+ {static} NormGetLocalNodeId(sessionHandle:long) : long
|
||||||
+ {static} NormGetAddress(sessionHandle:long, addrBuffer:string, bufferLen:uint) : bool
|
+ {static} NormSetTxPort(sessionHandle:long, txPortNumber:int, enableReuse:bool, txBindAddress:string) : bool
|
||||||
+ {static} NormGetAddress(sessionHandle:long, addrBuffer:string, bufferLen:uint, port:ushort) : bool
|
|
||||||
+ {static} NormGetRxPort(sessionHandle:long) : ushort
|
|
||||||
+ {static} NormSetTxPort(sessionHandle:long, txPortNumber:ushort) : bool
|
|
||||||
+ {static} NormSetTxPort(sessionHandle:long, txPortNumber:ushort, enableReuse:bool, txBindAddress:string) : bool
|
|
||||||
+ {static} NormGetTxPort(sessionHandle:long) : ushort
|
|
||||||
+ {static} NormSetTxOnly(sessionHandle:long, txOnly:bool) : void
|
|
||||||
+ {static} NormSetTxOnly(sessionHandle:long, txOnly:bool, connectToSessionAddress:bool) : void
|
+ {static} NormSetTxOnly(sessionHandle:long, txOnly:bool, connectToSessionAddress:bool) : void
|
||||||
+ {static} NormLimitObjectInfo(sessionHandle:long, state:bool) : void
|
+ {static} NormSetRxPortReuse(sessionHandle:long, enableReuse:bool, rxBindAddress:string, senderAddress:string, senderPort:int) : void
|
||||||
+ {static} NormPresetObjectInfo(sessionHandle:long, objectSize:ulong, segmentSize:ushort, numData:ushort, numParity:ushort) : bool
|
|
||||||
+ {static} NormSetId(sessionHandle:long, normId:long) : void
|
|
||||||
+ {static} NormChangeDestination(sessionHandle:long, sessionAddress:string, sessionPort:ushort) : bool
|
|
||||||
+ {static} NormChangeDestination(sessionHandle:long, sessionAddress:string, sessionPort:ushort, connectToSessionAddress:bool) : bool
|
|
||||||
+ {static} NormSetServerListner(sessionHandle:long, state:bool) : void
|
|
||||||
+ {static} NormTransferSender(sessionHandle:long, sender:long) : bool
|
|
||||||
+ {static} NormSetRxPortReuse(sessionHandle:long, enableReuse:bool) : void
|
|
||||||
+ {static} NormSetRxPortReuse(sessionHandle:long, enableReuse:bool, rxBindAddress:string, senderAddress:string, senderPort:ushort) : void
|
|
||||||
+ {static} NormGetRxBindAddress(sessionHandle:long, addr:string, addrLen:uint, port:ushort) : bool
|
|
||||||
+ {static} NormSetEcnSupport(sessionHandle:long, ecnEnable:bool) : void
|
|
||||||
+ {static} NormSetEcnSupport(sessionHandle:long, ecnEnable:bool, ignoreLoss:bool, tolerateLoss:bool) : void
|
+ {static} NormSetEcnSupport(sessionHandle:long, ecnEnable:bool, ignoreLoss:bool, tolerateLoss:bool) : void
|
||||||
+ {static} NormSetMulticastInterface(sessionHandle:long, interfaceName:string) : bool
|
+ {static} NormSetMulticastInterface(sessionHandle:long, interfaceName:string) : bool
|
||||||
+ {static} NormSetSSM(sessionHandle:long, sourceAddress:string) : bool
|
+ {static} NormSetSSM(sessionHandle:long, sourceAddress:string) : bool
|
||||||
+ {static} NormSetTTL(sessionHandle:long, ttl:byte) : bool
|
+ {static} NormSetTTL(sessionHandle:long, ttl:byte) : bool
|
||||||
+ {static} NormSetTOS(sessionHandle:long, tos:byte) : bool
|
+ {static} NormSetTOS(sessionHandle:long, tos:byte) : bool
|
||||||
+ {static} NormSetLoopback(sessionHandle:long, loopback:bool) : bool
|
+ {static} NormSetLoopback(sessionHandle:long, loopback:bool) : bool
|
||||||
+ {static} NormSetMulticastLoopback(sessionHandle:long, loopback:bool) : bool
|
|
||||||
+ {static} NormSetFragmentation(sessionHandle:long, fragmentation:bool) : bool
|
|
||||||
+ {static} NormSetMessageTrace(sessionHandle:long, state:bool) : void
|
+ {static} NormSetMessageTrace(sessionHandle:long, state:bool) : void
|
||||||
+ {static} NormSetTxLoss(sessionHandle:long, precent:double) : void
|
+ {static} NormSetTxLoss(sessionHandle:long, precent:double) : void
|
||||||
+ {static} NormSetRxLoss(sessionHandle:long, precent:double) : void
|
+ {static} NormSetRxLoss(sessionHandle:long, precent:double) : void
|
||||||
+ {static} NormOpenDebugLog(instanceHandle:long, path:string) : bool
|
+ {static} NormOpenDebugLog(instanceHandle:long, path:string) : bool
|
||||||
+ {static} NormCloseDebugLog(instanceHandle:long) : void
|
+ {static} NormCloseDebugLog(instanceHandle:long) : void
|
||||||
+ {static} NormOpenDebugPipe(instanceHandle:long, pipeName:string) : bool
|
+ {static} NormOpenDebugPipe(instanceHandle:long, pipeName:string) : bool
|
||||||
+ {static} NormCloseDebugPipe(instanceHandle:long) : void
|
|
||||||
+ {static} NormSetDebugLevel(level:int) : void
|
+ {static} NormSetDebugLevel(level:int) : void
|
||||||
+ {static} NormGetDebugLevel() : int
|
+ {static} NormGetDebugLevel() : int
|
||||||
+ {static} NormSetReportInterval(sessionHandle:long, interval:double) : void
|
+ {static} NormSetReportInterval(sessionHandle:long, interval:double) : void
|
||||||
+ {static} NormGetReportInterval(sessionHandle:long) : double
|
|
||||||
+ {static} NormGetRandomSessionId() : int
|
+ {static} NormGetRandomSessionId() : int
|
||||||
+ {static} NormStartSender(sessionHandle:long, instanceId:int, bufferSpace:long, segmentSize:int, numData:short, numParity:short) : bool
|
|
||||||
+ {static} NormStartSender(sessionHandle:long, instanceId:int, bufferSpace:long, segmentSize:int, numData:short, numParity:short, fecId:NormFecType) : bool
|
+ {static} NormStartSender(sessionHandle:long, instanceId:int, bufferSpace:long, segmentSize:int, numData:short, numParity:short, fecId:NormFecType) : bool
|
||||||
+ {static} NormStopSender(sessionHandle:long) : void
|
+ {static} NormStopSender(sessionHandle:long) : void
|
||||||
+ {static} NormSetTxRate(sessionHandle:long, bitsPerSecond:double) : void
|
+ {static} NormSetTxRate(sessionHandle:long, bitsPerSecond:double) : void
|
||||||
+ {static} NormGetTxRate(sessionHandle:long) : double
|
+ {static} NormGetTxRate(sessionHandle:long) : double
|
||||||
+ {static} NormSetTxSocketBuffer(sessionHandle:long, bufferSize:uint) : bool
|
+ {static} NormSetTxSocketBuffer(sessionHandle:long, bufferSize:long) : bool
|
||||||
+ {static} NormSetFlowControl(sessionHandle:long, flowControlFactor:double) : void
|
+ {static} NormSetFlowControl(sessionHandle:long, flowControlFactor:double) : void
|
||||||
+ {static} NormSetCongestionControl(sessionHandle:long, enable:bool) : void
|
|
||||||
+ {static} NormSetCongestionControl(sessionHandle:long, enable:bool, adjustRate:bool) : void
|
+ {static} NormSetCongestionControl(sessionHandle:long, enable:bool, adjustRate:bool) : void
|
||||||
+ {static} NormSetTxRateBounds(sessionHandle:long, rateMin:double, rateMax:double) : void
|
+ {static} NormSetTxRateBounds(sessionHandle:long, rateMin:double, rateMax:double) : void
|
||||||
+ {static} NormSetTxCacheBounds(sessionHandle:long, sizeMax:long, countMin:long, countMax:long) : void
|
+ {static} NormSetTxCacheBounds(sessionHandle:long, sizeMax:long, countMin:long, countMax:long) : void
|
||||||
|
|
@ -79,52 +55,32 @@ class NormApi
|
||||||
+ {static} NormSetGrttMax(sessionHandle:long, grttMax:double) : void
|
+ {static} NormSetGrttMax(sessionHandle:long, grttMax:double) : void
|
||||||
+ {static} NormSetGrttProbingMode(sessionHandle:long, probingMode:NormProbingMode) : void
|
+ {static} NormSetGrttProbingMode(sessionHandle:long, probingMode:NormProbingMode) : void
|
||||||
+ {static} NormSetGrttProbingInterval(sessionHandle:long, intervalMin:double, intervalMax:double) : void
|
+ {static} NormSetGrttProbingInterval(sessionHandle:long, intervalMin:double, intervalMax:double) : void
|
||||||
+ {static} NormSetGrttProbingTOS(sessionHandle:long, probeTOS:byte) : void
|
|
||||||
+ {static} NormSetBackoffFactor(sessionHandle:long, backoffFactor:double) : void
|
+ {static} NormSetBackoffFactor(sessionHandle:long, backoffFactor:double) : void
|
||||||
+ {static} NormSetGroupSize(sessionHandle:long, groupSize:uint) : void
|
+ {static} NormSetGroupSize(sessionHandle:long, groupSize:long) : void
|
||||||
+ {static} NormSetTxRobustFactor(sessionHandle:long, robustFactor:int) : void
|
+ {static} NormSetTxRobustFactor(sessionHandle:long, robustFactor:int) : void
|
||||||
+ {static} NormFileEnqueue(sessionHandle:long, fileName:string): long
|
|
||||||
+ {static} NormFileEnqueue(sessionHandle:long, fileName:string, infoPtr:string, infoLen:int): long
|
+ {static} NormFileEnqueue(sessionHandle:long, fileName:string, infoPtr:string, infoLen:int): long
|
||||||
+ {static} NormDataEnqueue(sessionHandle:long, dataPtr:string, dataLen:int) : long
|
+ {static} NormDataEnqueue(sessionHandle:long, dataPtr:byte[], dataLen:int, infoPtr:byte[], infoLen:int) : long
|
||||||
+ {static} NormDataEnqueue(sessionHandle:long, dataPtr:string, dataLen:int, infoPtr:string, infoLen:int) : long
|
|
||||||
+ {static} NormRequeueObject(sessionHandle:long, objectHandle:long) : bool
|
+ {static} NormRequeueObject(sessionHandle:long, objectHandle:long) : bool
|
||||||
+ {static} NormStreamOpen(sessionHandle:long, bufferSize:long) : long
|
|
||||||
+ {static} NormStreamOpen(sessionHandle:long, bufferSize:long, infoPtr:string, infoLen:int) : long
|
+ {static} NormStreamOpen(sessionHandle:long, bufferSize:long, infoPtr:string, infoLen:int) : long
|
||||||
+ {static} NormStreamClose(streamHandle:long) : void
|
|
||||||
+ {static} NormStreamClose(streamHandle:long, graceful:bool) : void
|
+ {static} NormStreamClose(streamHandle:long, graceful:bool) : void
|
||||||
+ {static} NormGetStreamBufferSegmentCount(bufferBytes:uint, segmentSize:ushort, blockSize:ushort) : uint
|
+ {static} NormStreamWrite(streamHandle:long, buffer:byte[], numBytes:int) : int
|
||||||
+ {static} NormStreamWrite(streamHandle:long, buffer:string, numBytes:uint) : uint
|
|
||||||
+ {static} NormStreamFlush(streamHandle:long) : void
|
|
||||||
+ {static} NormStreamFlush(streamHandle:long, eom:bool, flushMode:NormFlushMode) : void
|
+ {static} NormStreamFlush(streamHandle:long, eom:bool, flushMode:NormFlushMode) : void
|
||||||
+ {static} NormStreamSetAutoFlush(streamHandle:long, flushMode: NormFlushMode) : void
|
+ {static} NormStreamSetAutoFlush(streamHandle:long, flushMode: NormFlushMode) : void
|
||||||
+ {static} NormStreamSetPushEnable(streamHandle:long, pushEnable:bool) : void
|
+ {static} NormStreamSetPushEnable(streamHandle:long, pushEnable:bool) : void
|
||||||
+ {static} NormStreamHasVacancy(streamHandle:long) : bool
|
+ {static} NormStreamHasVacancy(streamHandle:long) : bool
|
||||||
+ {static} NormStreamGetVacancy(streamHandle:long, bytesWanted:uint) : uint
|
|
||||||
+ {static} NormStreamMarkEom(streamHandle:long) : void
|
+ {static} NormStreamMarkEom(streamHandle:long) : void
|
||||||
+ {static} NormSetWatermark(sessionHandle:long, objectHandle:long) : bool
|
|
||||||
+ {static} NormSetWatermark(sessionHandle:long, objectHandle:long, overrideFlush:bool) : bool
|
+ {static} NormSetWatermark(sessionHandle:long, objectHandle:long, overrideFlush:bool) : bool
|
||||||
+ {static} NormSetWatermarkEx(sessionHandle:long, objectHandle:long, buffer:string, numBytes:uint) : bool
|
|
||||||
+ {static} NormSetWatermarkEx(sessionHandle:long, objectHandle:long, buffer:string, numBytes:uint, overrideFlush:bool) : bool
|
|
||||||
+ {static} NormResetWatermark(sessionHandle:long) : bool
|
+ {static} NormResetWatermark(sessionHandle:long) : bool
|
||||||
+ {static} NormCancelWatermark(sessionHandle:long) : void
|
+ {static} NormCancelWatermark(sessionHandle:long) : void
|
||||||
+ {static} NormAddAckingNode(sessionHandle:long, nodeId:long) : bool
|
+ {static} NormAddAckingNode(sessionHandle:long, nodeId:long) : bool
|
||||||
+ {static} NormRemoveAckingNode(sessionHandle:long, nodeId:long) : void
|
+ {static} NormRemoveAckingNode(sessionHandle:long, nodeId:long) : void
|
||||||
+ {static} NormGetAckingNodeHandle(sessionHandle:long, nodeId:long) : long
|
|
||||||
+ {static} NormSetAutoAckingNodes(sessionHandle:long, trackingStatus:NormTrackingStatus) : void
|
|
||||||
+ {static} NormGetAckingStatus(sessionHandle:long) : NormAckingStatus
|
|
||||||
+ {static} NormGetAckingStatus(sessionHandle:long, nodeId:long) : NormAckingStatus
|
+ {static} NormGetAckingStatus(sessionHandle:long, nodeId:long) : NormAckingStatus
|
||||||
+ {static} NormGetNextAckingNode(sessionHandle:long, nodeId:long) : bool
|
+ {static} NormSendCommand(sessionHandle:long, cmdBuffer:byte[], cmdLength:int, robust:bool) : bool
|
||||||
+ {static} NormGetNextAckingNode(sessionHandle:long, nodeId:long, ackingStatus:NormAckingStatus) : bool
|
|
||||||
+ {static} NormGetAckEx(sessionHandle:long, nodeId:long, buffer:string, buflen:uint) : bool
|
|
||||||
+ {static} NormSendCommand(sessionHandle:long, cmdBuffer:string, cmdLength:uint) : bool
|
|
||||||
+ {static} NormSendCommand(sessionHandle:long, cmdBuffer:string, cmdLength:uint, robust:bool) : bool
|
|
||||||
+ {static} NormCancelCommand(sessionHandle:long) : void
|
+ {static} NormCancelCommand(sessionHandle:long) : void
|
||||||
+ {static} NormSetSynStatus(sessionHandle:long, state:bool) : void
|
|
||||||
+ {static} NormStartReceiver(sessionHandle:long, bufferSpace:long) : bool
|
+ {static} NormStartReceiver(sessionHandle:long, bufferSpace:long) : bool
|
||||||
+ {static} NormStopReceiver(sessionHandle:long) : void
|
+ {static} NormStopReceiver(sessionHandle:long) : void
|
||||||
+ {static} NormSetRxCacheLimit(sessionHandle:long, countMax:ushort) : void
|
+ {static} NormSetRxCacheLimit(sessionHandle:long, countMax:int) : void
|
||||||
+ {static} NormSetRxSocketBuffer(sessionHandle:long, bufferSize:uint) : bool
|
+ {static} NormSetRxSocketBuffer(sessionHandle:long, bufferSize:long) : bool
|
||||||
+ {static} NormSetSilentReceiver(sessionHandle:long, silent:bool) : void
|
|
||||||
+ {static} NormSetSilentReceiver(sessionHandle:long, silent:bool, maxDelay:int) : void
|
+ {static} NormSetSilentReceiver(sessionHandle:long, silent:bool, maxDelay:int) : void
|
||||||
+ {static} NormSetDefaultUnicastNack(sessionHandle:long, unicastNacks:bool) : void
|
+ {static} NormSetDefaultUnicastNack(sessionHandle:long, unicastNacks:bool) : void
|
||||||
+ {static} NormNodeSetUnicastNack(remoteSender:long, unicastNacks:bool) : void
|
+ {static} NormNodeSetUnicastNack(remoteSender:long, unicastNacks:bool) : void
|
||||||
|
|
@ -135,17 +91,14 @@ class NormApi
|
||||||
+ {static} NormSetDefaultRepairBoundary(sessionHandle:long, repairBoundary:NormRepairBoundary) : void
|
+ {static} NormSetDefaultRepairBoundary(sessionHandle:long, repairBoundary:NormRepairBoundary) : void
|
||||||
+ {static} NormNodeSetRepairBoundary(remoteSender:long, repairBoundary:NormRepairBoundary) : void
|
+ {static} NormNodeSetRepairBoundary(remoteSender:long, repairBoundary:NormRepairBoundary) : void
|
||||||
+ {static} NormSetDefaultRxRobustFactor(sessionHandle:long, robustFactor:int) : void
|
+ {static} NormSetDefaultRxRobustFactor(sessionHandle:long, robustFactor:int) : void
|
||||||
+ {static} NormNodeSetRxRobustFactor(remoteSenderremoteSender, robustFactor:int) : void
|
+ {static} NormNodeSetRxRobustFactor(remoteSender:long, robustFactor:int) : void
|
||||||
+ {static} NormPreallocateRemoteSender(sessionHandle:long, bufferSize:ulong, segmentSize:ushort, numData:ushort, numParity:ushort) : bool
|
+ {static} NormStreamRead(streamHandle:long, buffer:byte[], numBytes:int) : bool
|
||||||
+ {static} NormPreallocateRemoteSender(sessionHandle:long, bufferSize:ulong, segmentSize:ushort, numData:ushort, numParity:ushort, streamBufferSize:uint) : bool
|
|
||||||
+ {static} NormStreamRead(streamHandle:long, buffer:string, numBytes:uint) : bool
|
|
||||||
+ {static} NormStreamSeekMsgStart(streamHandle:long) : bool
|
+ {static} NormStreamSeekMsgStart(streamHandle:long) : bool
|
||||||
+ {static} NormStreamGetReadOffset(streamHandle:long) : uint
|
+ {static} NormStreamGetReadOffset(streamHandle:long) : long
|
||||||
+ {static} NormStreamGetBufferUsage(streamHandle:long) : uint
|
|
||||||
+ {static} NormObjectGetType(objectHandle:long) : NormObjectType
|
+ {static} NormObjectGetType(objectHandle:long) : NormObjectType
|
||||||
+ {static} NormObjectHasInfo(objectHandle:long) : bool
|
+ {static} NormObjectHasInfo(objectHandle:long) : bool
|
||||||
+ {static} NormObjectGetInfoLength(objectHandle:long) : ushort
|
+ {static} NormObjectGetInfoLength(objectHandle:long) : int
|
||||||
+ {static} NormObjectGetInfo(objectHandle:long, buffer:char, bufferLen:ushort) : ushort
|
+ {static} NormObjectGetInfo(objectHandle:long, buffer:byte[], bufferLen:int) : int
|
||||||
+ {static} NormObjectGetSize(objectHandle:long) : int
|
+ {static} NormObjectGetSize(objectHandle:long) : int
|
||||||
+ {static} NormObjectGetBytesPending(objectHandle:long) : int
|
+ {static} NormObjectGetBytesPending(objectHandle:long) : int
|
||||||
+ {static} NormObjectCancel(objectHandle:long) : void
|
+ {static} NormObjectCancel(objectHandle:long) : void
|
||||||
|
|
@ -153,24 +106,14 @@ class NormApi
|
||||||
+ {static} NormObjectRelease(objectHandle:long) : void
|
+ {static} NormObjectRelease(objectHandle:long) : void
|
||||||
+ {static} NormFileGetName(fileHandle:long, nameBuffer:string, bufferLen:int) : bool
|
+ {static} NormFileGetName(fileHandle:long, nameBuffer:string, bufferLen:int) : bool
|
||||||
+ {static} NormFileRename(fileHandle:long, fileName:string) : bool
|
+ {static} NormFileRename(fileHandle:long, fileName:string) : bool
|
||||||
+ {static} NormDataAccessData(objectHandle:long) : string
|
+ {static} NormDataAccessData(objectHandle:long) : nint
|
||||||
+ {static} NormDataDetachData(objectHandle:long) : string
|
|
||||||
+ {static} NormObjectGetSender(objectHandle:long) : long
|
+ {static} NormObjectGetSender(objectHandle:long) : long
|
||||||
+ {static} NormNodeGetId(nodeHandle:long) : uint
|
+ {static} NormNodeGetId(nodeHandle:long) : long
|
||||||
+ {static} NormNodeGetAddress(nodeHandle:long, addrBuffer:string, bufferLen: uint) : bool
|
+ {static} NormNodeGetAddress(nodeHandle:long, addrBuffer:byte[], bufferLen: int, port:int) : bool
|
||||||
+ {static} NormNodeGetAddress(nodeHandle:long, addrBuffer:string, bufferLen: uint, port:ushort) : bool
|
|
||||||
+ {static} NormNodeGetGrtt(remoteSender:long) : double
|
+ {static} NormNodeGetGrtt(remoteSender:long) : double
|
||||||
+ {static} NormNodeGetCommand(remoteSender:long, :string, buflen:uint) : bool
|
+ {static} NormNodeGetCommand(remoteSender:long, buffer:byte[], buflen:int) : bool
|
||||||
+ {static} NormNodeSendAckEx(remoteSender:long, buffer:string, numBytes:uint) : bool
|
|
||||||
+ {static} NormNodeGetWatermarkEx(remoteSender:long, buffer:string, buflen:uint) : bool
|
|
||||||
+ {static} NormNodeFreeBuffers(remoteSender:long) : void
|
+ {static} NormNodeFreeBuffers(remoteSender:long) : void
|
||||||
+ {static} NormNodeDelete(remoteSender:long) : void
|
|
||||||
+ {static} NormNodeRetain(nodeHandle:long) : void
|
+ {static} NormNodeRetain(nodeHandle:long) : void
|
||||||
+ {static} NormNodeRelease(nodeHandle:long) : void
|
+ {static} NormNodeRelease(nodeHandle:long) : void
|
||||||
+ {static} NormReleasePreviousEvent(instanceHandle:long) : void
|
|
||||||
+ {static} NormCountCompletedObjects(sessionHandle:long) : uint
|
|
||||||
+ {static} NormNodeSetAutoDelete(remoteSender:long, autoDelete:bool) : void
|
|
||||||
+ {static} NormNodeAllowSender(senderId:long) : bool
|
|
||||||
+ {static} NormNodeDenySender(senderId:long) : bool
|
|
||||||
}
|
}
|
||||||
@enduml
|
@enduml
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
@startuml
|
@startuml
|
||||||
class NormFile {
|
class NormFile {
|
||||||
|
+ <<const>> FILENAME_MAX : int = 260
|
||||||
~ NormFile(handle:long)
|
~ NormFile(handle:long)
|
||||||
+ Name : string <<get>>
|
+ Name : string <<get>>
|
||||||
+ Rename(filename:string) : void
|
+ Rename(filename:string) : void
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
@startuml
|
@startuml
|
||||||
class NormInstance {
|
class NormInstance {
|
||||||
|
+ <<const>> NORM_DESCRIPTOR_INVALID : int = 0
|
||||||
- _handle: long
|
- _handle: long
|
||||||
+ NormInstance()
|
+ NormInstance()
|
||||||
+ NormInstance(priorityBoost:bool)
|
+ NormInstance(priorityBoost:bool)
|
||||||
|
|
@ -14,7 +15,9 @@ class NormInstance {
|
||||||
+ CloseDebugLog() : void
|
+ CloseDebugLog() : void
|
||||||
+ OpenDebugPipe(pipename:string) : void
|
+ OpenDebugPipe(pipename:string) : void
|
||||||
+ DebugLevel: int <<get>> <<set>>
|
+ DebugLevel: int <<get>> <<set>>
|
||||||
+ HasNextEvent(sec:int, usec:int) : boolean
|
+ HasNextEvent(sec:int, usec:int) : bool
|
||||||
|
+ HasNextEvent(waitTime:TimeSpan) : bool
|
||||||
|
+ GetNextEvent(waitForEvent:bool) : NormEvent
|
||||||
+ GetNextEvent() : NormEvent
|
+ GetNextEvent() : NormEvent
|
||||||
+ CreateSession(address:string, port:int, localNodeId:long) : NormSession
|
+ CreateSession(address:string, port:int, localNodeId:long) : NormSession
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
@startuml
|
@startuml
|
||||||
class NormNode {
|
class NormNode {
|
||||||
+ <<const>> NORM_NODE_ANY : long = 0xffffffff
|
+ <<const>> NORM_NODE_ANY : long = 0xffffffff
|
||||||
|
+ <<const>> NORM_NODE_NONE : int = 0
|
||||||
|
+ <<const>> NORM_NODE_INVALID : int = 0
|
||||||
- _handle : long
|
- _handle : long
|
||||||
~ NormNode(handle:long)
|
~ NormNode(handle:long)
|
||||||
+ SetUnicastNack(state:bool) : void
|
+ SetUnicastNack(state:bool) : void
|
||||||
|
|
@ -8,9 +10,9 @@ class NormNode {
|
||||||
+ SetRepairBoundary(repairBoundary:NormRepairBoundary) : void
|
+ SetRepairBoundary(repairBoundary:NormRepairBoundary) : void
|
||||||
+ SetRxRobustFactor(robustFactor:int) : void
|
+ SetRxRobustFactor(robustFactor:int) : void
|
||||||
+ Id : long <<get>>
|
+ Id : long <<get>>
|
||||||
+ Address : SocketAddress <<get>>
|
+ Address : IPEndPoint <<get>>
|
||||||
+ Grtt : double <<get>>
|
+ Grtt : double <<get>>
|
||||||
+ GetCommand(buffer:byte[], offset:int, length:int) : int
|
+ Command : byte[] <<get>>
|
||||||
+ FreeBuffers() : void
|
+ FreeBuffers() : void
|
||||||
+ Retain() : void
|
+ Retain() : void
|
||||||
+ Release(): void
|
+ Release(): void
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
@startuml
|
@startuml
|
||||||
class NormObject {
|
class NormObject {
|
||||||
|
+ <<const>> NORM_OBJECT_INVALID : int = 0
|
||||||
# _handle:long
|
# _handle:long
|
||||||
~ NormObject(handle:long)
|
~ NormObject(handle:long)
|
||||||
+ SetNackingMode(nackingMode:NormNackingMode) : void
|
+ SetNackingMode(nackingMode:NormNackingMode) : void
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
@startuml
|
@startuml
|
||||||
class NormSession {
|
class NormSession {
|
||||||
|
+ <<const>> NORM_SESSION_INVALID : int = 0
|
||||||
{static} -_normSessions : Dictionary<long, NormSession>
|
{static} -_normSessions : Dictionary<long, NormSession>
|
||||||
- _handle : long
|
- _handle : long
|
||||||
~ NormSession(handle:long)
|
~ NormSession(handle:long)
|
||||||
|
|
@ -22,8 +23,10 @@ class NormSession {
|
||||||
+ SetTxLoss(precent:double) : void
|
+ SetTxLoss(precent:double) : void
|
||||||
+ SetRxLoss(precent:double) : void
|
+ SetRxLoss(precent:double) : void
|
||||||
+ ReportInterval: double <<get>> <<set>>
|
+ ReportInterval: double <<get>> <<set>>
|
||||||
+ StartSender(sessionId:int, bufferSpace:long, segmentSize:int, blockSize:short, numParity:short) : 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, 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
|
+ StopSender() : void
|
||||||
+ SetTxOnly(txOnly:bool) : void
|
+ SetTxOnly(txOnly:bool) : void
|
||||||
+ TxRate:double <<get>> <<set>>
|
+ TxRate:double <<get>> <<set>>
|
||||||
|
|
@ -43,11 +46,12 @@ class NormSession {
|
||||||
+ SetTxRobustFactor(robustFactor:int) : void
|
+ SetTxRobustFactor(robustFactor:int) : void
|
||||||
+ FileEnqueue(filename:string) : NormFile
|
+ FileEnqueue(filename:string) : NormFile
|
||||||
+ FileEnqueue(filename:string, info:byte[], infoOffset:int, infoLength:int) : NormFile
|
+ FileEnqueue(filename:string, info:byte[], infoOffset:int, infoLength:int) : NormFile
|
||||||
+ DataEnqueue(dataBuffer:MemoryStream, dataOffset:int, dataLength:int) : NormData
|
+ DataEnqueue(dataBuffer:byte[], dataLength:int) : NormData
|
||||||
+ DataEnqueue(dataBuffer:MemoryStream, dataOffset:int, dataLength:int, info:byte[], infoOffset:int, infoLength:int) : NormData
|
+ DataEnqueue(dataBuffer:byte[], dataOffset:int, dataLength:int, info:byte[], infoOffset:int, infoLength:int) : NormData
|
||||||
+ RequeueObject(object:NormObject) : void
|
+ RequeueObject(object:NormObject) : void
|
||||||
+ StreamOpen(bufferSize:long) : NormStream
|
+ StreamOpen(bufferSize:long) : NormStream
|
||||||
+ StreamOpen(bufferSize:long, info:byte[], infoOffset:int, infoLength:int) : NormStream
|
+ StreamOpen(bufferSize:long, info:byte[], infoOffset:int, infoLength:int) : NormStream
|
||||||
|
+ SetWatermark(object:NormObject) : void
|
||||||
+ SetWatermark(object:NormObject, overrideFlush:bool) : void
|
+ SetWatermark(object:NormObject, overrideFlush:bool) : void
|
||||||
+ CancelWatermark() : void
|
+ CancelWatermark() : void
|
||||||
+ ResetWatermark() : void
|
+ ResetWatermark() : void
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,5 @@ class NormStream {
|
||||||
+ SeekMsgStart() : bool
|
+ SeekMsgStart() : bool
|
||||||
+ ReadOffset : long <<get>>
|
+ ReadOffset : long <<get>>
|
||||||
}
|
}
|
||||||
|
NormObject <|-- NormStream
|
||||||
@enduml
|
@enduml
|
||||||
|
|
@ -7,7 +7,7 @@ Client <- NormInstance : NormInstance
|
||||||
Client -> NormInstance : CreateSession(address, port, localNodeId)
|
Client -> NormInstance : CreateSession(address, port, localNodeId)
|
||||||
NormInstance -> NormApi : NormCreateSession(instanceHandle, address, port, localNodeId)
|
NormInstance -> NormApi : NormCreateSession(instanceHandle, address, port, localNodeId)
|
||||||
NormInstance <- NormApi : sessionHandle
|
NormInstance <- NormApi : sessionHandle
|
||||||
alt sessionHandle == NORM_SESSION_INVALID
|
alt sessionHandle == NormApi.NORM_SESSION_INVALID
|
||||||
NormInstance -> IOException : throw new("Failed to create session")
|
NormInstance -> IOException : throw new("Failed to create session")
|
||||||
end
|
end
|
||||||
NormInstance -> NormSession : new(sessionHandle)
|
NormInstance -> NormSession : new(sessionHandle)
|
||||||
|
|
@ -30,9 +30,9 @@ end
|
||||||
NormSession -> NormFile: new(objectHandle)
|
NormSession -> NormFile: new(objectHandle)
|
||||||
NormSession <- NormFile : NormFile
|
NormSession <- NormFile : NormFile
|
||||||
Client <- NormSession : NormFile
|
Client <- NormSession : NormFile
|
||||||
loop NormEvent != null
|
loop NormInstance.HasNextEvent(waitTime)
|
||||||
Client -> NormInstance : GetNextEvent()
|
Client -> NormInstance : GetNextEvent(false)
|
||||||
NormInstance -> NormApi : NormGetNextEvent(instanceHandle, NormEvent)
|
NormInstance -> NormApi : NormGetNextEvent(instanceHandle, NormEvent, false)
|
||||||
NormInstance <- NormApi : success
|
NormInstance <- NormApi : success
|
||||||
alt success == false
|
alt success == false
|
||||||
Client <- NormInstance : null
|
Client <- NormInstance : null
|
||||||
|
|
|
||||||
|
|
@ -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,10 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Mil.Navy.Nrl.Norm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A transport object of type NORM_OBJECT_FILE.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The data storage area for the specified transport object.
|
||||||
|
/// </remarks>
|
||||||
|
public class NormData : NormObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The data storage area associated with a transport object of type NORM_OBJECT_DATA.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Data
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var dataPointer = NormDataAccessData(_handle);
|
||||||
|
var length = NormObjectGetSize(_handle);
|
||||||
|
var data = new byte[length];
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
data[i] = Marshal.ReadByte(dataPointer, i);
|
||||||
|
}
|
||||||
|
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,54 @@
|
||||||
|
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 string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var buffer = new char[FILENAME_MAX];
|
||||||
|
if (!NormFileGetName(_handle, buffer, FILENAME_MAX))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to get file name");
|
||||||
|
}
|
||||||
|
buffer = buffer.Where(c => c != 0).ToArray();
|
||||||
|
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,236 @@
|
||||||
|
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 a default function which calls GetNextEvent(bool waitForEvent) override
|
||||||
|
/// 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,147 @@
|
||||||
|
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 IPEndPoint Address
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var buffer = new byte[256];
|
||||||
|
var bufferLength = buffer.Length;
|
||||||
|
if (!NormNodeGetAddress(_handle, buffer, ref bufferLength, out var port))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to get node address");
|
||||||
|
}
|
||||||
|
buffer = buffer.Take(bufferLength).ToArray();
|
||||||
|
var ipAddressText = string.Join('.', buffer);
|
||||||
|
var ipAddress = IPAddress.Parse(ipAddressText);
|
||||||
|
|
||||||
|
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>
|
||||||
|
/// NORM application-defined command for transmission.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Command
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var buffer = new byte[256];
|
||||||
|
var bufferLength = buffer.Length;
|
||||||
|
if (!NormNodeGetCommand(_handle, buffer, ref bufferLength))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to get command");
|
||||||
|
}
|
||||||
|
return buffer.Take(bufferLength).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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,163 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,923 @@
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Mil.Navy.Nrl.Norm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// NORM transport session
|
||||||
|
/// </summary>
|
||||||
|
public class NormSession
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The special value NORM_SESSION_INVALID is used to refer to invalid session references.
|
||||||
|
/// </summary>
|
||||||
|
public const int NORM_SESSION_INVALID = 0;
|
||||||
|
/// <summary>
|
||||||
|
/// A dictionary of NORM sessions with their respective handles.
|
||||||
|
/// </summary>
|
||||||
|
private static Dictionary<long, NormSession> _normSessions = new Dictionary<long, NormSession>();
|
||||||
|
/// <summary>
|
||||||
|
/// The NormSessionHandle type is used to reference the NORM transport session.
|
||||||
|
/// </summary>
|
||||||
|
private long _handle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used for the application's participation in the NormSession.
|
||||||
|
/// </summary>
|
||||||
|
public long LocalNodeId
|
||||||
|
{
|
||||||
|
get => NormGetLocalNodeId(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The report interval.
|
||||||
|
/// </summary>
|
||||||
|
public double ReportInterval
|
||||||
|
{
|
||||||
|
get => NormGetReportInterval(_handle);
|
||||||
|
set => NormSetReportInterval(_handle, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transmission rate (in bits per second (bps)) limit used for NormSender transmissions.
|
||||||
|
/// </summary>
|
||||||
|
public double TxRate
|
||||||
|
{
|
||||||
|
get => NormGetTxRate(_handle);
|
||||||
|
set => NormSetTxRate(_handle, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Group round-trip timing.
|
||||||
|
/// </summary>
|
||||||
|
public double GrttEstimate
|
||||||
|
{
|
||||||
|
get => NormGetGrttEstimate(_handle);
|
||||||
|
set => NormSetGrttEstimate(_handle, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal constructor of NormSession.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handle">Used to identify application in the NormSession.</param>
|
||||||
|
/// <remarks>The handle and NormSession are added to the dictionary of NORM sessions.</remarks>
|
||||||
|
internal NormSession(long handle)
|
||||||
|
{
|
||||||
|
_handle = handle;
|
||||||
|
lock (_normSessions)
|
||||||
|
{
|
||||||
|
_normSessions.Add(handle, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a specified NormSession from the dictionary of NORM sessions.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handle">Specifies the session to return.</param>
|
||||||
|
/// <returns>Returns a NormSession.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||||
|
internal static NormSession GetSession(long handle)
|
||||||
|
{
|
||||||
|
return _normSessions[handle];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function immediately terminates the application's participation in the NormSession and frees any resources used by that session.
|
||||||
|
/// </summary>
|
||||||
|
public void DestroySession()
|
||||||
|
{
|
||||||
|
lock (_normSessions)
|
||||||
|
{
|
||||||
|
_normSessions.Remove(_handle);
|
||||||
|
}
|
||||||
|
DestroySessionNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function immediately terminates the application's participation in the NormSession and frees any resources used by that session.
|
||||||
|
/// </summary>
|
||||||
|
private void DestroySessionNative()
|
||||||
|
{
|
||||||
|
NormDestroySession(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function is used to force NORM to use a specific port number for UDP packets sent.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a default function which calls SetTxPort(int port, bool enableReuse, string? txBindAddress) override
|
||||||
|
/// with enableReuse set as false and txBindAddress set to null.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="port">The port parameter, specifies which port number to use.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetTxPort() returns false, indicating the failure to set tx port.</exception>
|
||||||
|
public void SetTxPort(int port)
|
||||||
|
{
|
||||||
|
SetTxPort(port, false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function is used to force NORM to use a specific port number for UDP packets sent.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="port">The port parameter, specifies which port number to use.</param>
|
||||||
|
/// <param name="enableReuse">When set to true, allows that the specified port may be reused for multiple sessions.</param>
|
||||||
|
/// <param name="txBindAddress">The txBindAddress parameter allows specification of a specific source address binding for packet transmission.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetTxPort() returns false, indicating the failure to set tx port.</exception>
|
||||||
|
public void SetTxPort(int port, bool enableReuse, string? txBindAddress)
|
||||||
|
{
|
||||||
|
if (!NormSetTxPort(_handle, port, enableReuse, txBindAddress))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set Tx Port");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function limits the NormSession to perform NORM sender functions only.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a default function which calls etTxOnly(bool txOnly, bool connectToSessionAddress) override
|
||||||
|
/// with connectToSessionAddress set as false.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="txOnly">Boolean specifing whether to turn on or off the txOnly operation.</param>
|
||||||
|
public void SetTxOnly(bool txOnly)
|
||||||
|
{
|
||||||
|
SetTxOnly(txOnly, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function limits the NormSession to perform NORM sender functions only.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="txOnly">Boolean specifing whether to turn on or off the txOnly operation.</param>
|
||||||
|
/// <param name="connectToSessionAddress">The optional connectToSessionAddress parameter, when set to true, causes the underlying NORM code to
|
||||||
|
/// "connect()" the UDP socket to the session (remote receiver) address and port number.</param>
|
||||||
|
public void SetTxOnly(bool txOnly, bool connectToSessionAddress)
|
||||||
|
{
|
||||||
|
NormSetTxOnly(_handle, txOnly, connectToSessionAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function allows the user to control the port reuse and binding behavior for the receive socket.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a default function which calls SetRxPortReuse(bool enable, string? rxBindAddress, string? senderAddress, int senderPort)
|
||||||
|
/// with rxBindAddress set to null, senderAddress set to null, and senderPort set to 0.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="enable">When the enable parameter is set to true, reuse of the NormSession port number by multiple NORM instances or sessions is enabled.</param>
|
||||||
|
public void SetRxPortReuse(bool enable)
|
||||||
|
{
|
||||||
|
SetRxPortReuse(enable, null, null, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function allows the user to control the port reuse and binding behavior for the receive socket.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enable">When the enable parameter is set to true, reuse of the NormSession port number by multiple NORM instances or sessions is enabled.</param>
|
||||||
|
/// <param name="rxBindAddress">If the optional rxBindAddress is supplied (an IP address or host name in string form),
|
||||||
|
/// the socket will bind() to the given address when it is opened in a call to StartReceiver() or StartSender().</param>
|
||||||
|
/// <param name="senderAddress">The optional senderAddress parameter can be used to connect() the underlying NORM receive socket to specific address.</param>
|
||||||
|
/// <param name="senderPort">The optional senderPort parameter can be used to connect() the underlying NORM receive socket to specific port.</param>
|
||||||
|
public void SetRxPortReuse(bool enable, string? rxBindAddress, string? senderAddress, int senderPort)
|
||||||
|
{
|
||||||
|
NormSetRxPortReuse(_handle, enable, rxBindAddress, senderAddress, senderPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a default function which calls SetEcnSupport(bool ecnEnable, bool ignoreLoss, bool tolerateLoss) override
|
||||||
|
/// with tolerateLoss set as false.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="ecnEnable">Enables NORM ECN (congestion control) support.</param>
|
||||||
|
/// <param name="ignoreLoss">With "ecnEnable", use ECN-only, ignoring packet loss.</param>
|
||||||
|
public void SetEcnSupport(bool ecnEnable, bool ignoreLoss)
|
||||||
|
{
|
||||||
|
SetEcnSupport(ecnEnable, ignoreLoss, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <param name="ecnEnable">Enables NORM ECN (congestion control) support.</param>
|
||||||
|
/// <param name="ignoreLoss">With "ecnEnable", use ECN-only, ignoring packet loss.</param>
|
||||||
|
/// <param name="tolerateLoss">Loss-tolerant congestion control, ecnEnable or not.</param>
|
||||||
|
public void SetEcnSupport(bool ecnEnable, bool ignoreLoss, bool tolerateLoss)
|
||||||
|
{
|
||||||
|
NormSetEcnSupport(_handle, ecnEnable, ignoreLoss, tolerateLoss);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function specifies which host network interface is used for IP Multicast transmissions and group membership.
|
||||||
|
/// This should be called before any call to StartSender() or StartReceiver() is made so that the IP multicast
|
||||||
|
/// group is joined on the proper host interface.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="interfaceName">Name of the interface</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetMulticastInterface() returns false, indicating the failure to set multicast interface.</exception>
|
||||||
|
public void SetMulticastInterface(string interfaceName)
|
||||||
|
{
|
||||||
|
if(!NormSetMulticastInterface(_handle, interfaceName))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set multicast interface");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the source address for Source-Specific Multicast (SSM) operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceAddress">Address to be set as source for source-specific multicast operation. </param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetSSM() returns false, indicating the failure to set ssm.</exception>
|
||||||
|
public void SetSSM(string sourceAddress)
|
||||||
|
{
|
||||||
|
if(!NormSetSSM(_handle, sourceAddress))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set SSM");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function specifies the time-to-live (ttl) for IP Multicast datagrams generated by NORM for the specified
|
||||||
|
/// sessionHandle. The IP TTL field limits the number of router "hops" that a generated multicast packet may traverse
|
||||||
|
/// before being dropped.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ttl">If TTL is equal to one, the transmissions will be limited to the local area network
|
||||||
|
/// (LAN) of the host computers network interface. Larger TTL values should be specified to span large networks.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetTTL() returns false, indicating the failure to set ttl.</exception>
|
||||||
|
public void SetTTL(byte ttl)
|
||||||
|
{
|
||||||
|
if (!NormSetTTL(_handle, ttl))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set TTL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function specifies the type-of-service (tos) field value used in IP Multicast datagrams generated by NORM.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tos">The IP TOS field value can be used as an indicator that a "flow" of packets may merit special Quality-of-Service (QoS) treatment by network devices.
|
||||||
|
/// Users should refer to applicable QoS information for their network to determine the expected interpretation and treatment (if any) of packets with explicit TOS marking.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetTOS() returns false, indicating the failure to set TOS.</exception>
|
||||||
|
public void SetTOS(byte tos)
|
||||||
|
{
|
||||||
|
if(!NormSetTOS(_handle, tos))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set TOS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function enables or disables loopback operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loopbackEnable">If loopbackEnable is set to true, loopback operation is enabled which allows the application to receive its own message traffic.
|
||||||
|
/// Thus, an application which is both actively receiving and sending may receive its own transmissions.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetLoopback() returns false, indicating the failure to set loopback.</exception>
|
||||||
|
public void SetLoopback(bool loopbackEnable)
|
||||||
|
{
|
||||||
|
if (!NormSetLoopback(_handle, loopbackEnable))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set loopback");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMessageTrace(bool flag)
|
||||||
|
{
|
||||||
|
NormSetMessageTrace(_handle, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTxLoss(double precent)
|
||||||
|
{
|
||||||
|
NormSetTxLoss(_handle, precent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetRxLoss(double precent)
|
||||||
|
{
|
||||||
|
NormSetRxLoss(_handle, precent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function controls a scaling factor that is used for sender timer-based flow control.
|
||||||
|
/// Timer-based flow control works by preventing the NORM sender application from enqueueing
|
||||||
|
/// new transmit objects or stream data that would purge "old" objects or stream data when there has been recent
|
||||||
|
/// NACK activity for those old objects or data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="precent">The precent is used to compute a delay time for when a sender buffered object (or block of stream
|
||||||
|
/// data) may be released (i.e. purged) after transmission or applicable NACKs reception. </param>
|
||||||
|
public void SetFlowControl(double precent)
|
||||||
|
{
|
||||||
|
NormSetFlowControl(_handle, precent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function can be used to set a non-default socket buffer size for the UDP socket used for data transmission.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bufferSize">The bufferSize parameter specifies the desired socket buffer size in bytes.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetTxSocketBuffer() returns false, indicating the failure to set tx socket buffer.
|
||||||
|
/// Possible failure modes include an invalid sessionHandle parameter, a call to StartReceiver() or StartSender() has not yet been made for the
|
||||||
|
/// session, or an invalid bufferSize was given.
|
||||||
|
/// Note some operating systems may require additional system configuration to use non-standard socket buffer sizes.</exception>
|
||||||
|
public void SetTxSocketBuffer(long bufferSize)
|
||||||
|
{
|
||||||
|
if(!NormSetTxSocketBuffer(_handle, bufferSize))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set tx socket buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function enables (or disables) the NORM sender congestion control operation.
|
||||||
|
/// For best operation, this function should be called before the call to StartSender() is made,
|
||||||
|
/// but congestion control operation can be dynamically enabled/disabled during the course of sender operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is the default function which calls SetCongestionControl(bool enable, bool adjustRate) override
|
||||||
|
/// with adjustRate set to true.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="enable">Specifies whether to enable or disable the NORM sender congestion control operation.</param>
|
||||||
|
public void SetCongestionControl(bool enable)
|
||||||
|
{
|
||||||
|
SetCongestionControl(enable, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function enables (or disables) the NORM sender congestion control operation.
|
||||||
|
/// For best operation, this function should be called before the call to StartSender() is made,
|
||||||
|
/// but congestion control operation can be dynamically enabled/disabled during the course of sender operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enable">Specifies whether to enable or disable the NORM sender congestion control operation.</param>
|
||||||
|
/// <param name="adjustRate">The rate set by SetTxRate() has no effect when congestion control operation is enabled, unless the adjustRate
|
||||||
|
/// parameter here is set to false. When the adjustRate parameter is set to false, the NORM Congestion Control
|
||||||
|
/// operates as usual, with feedback collected from the receiver set and the "current limiting receiver" identified, except
|
||||||
|
/// that no actual adjustment is made to the sender's transmission rate.</param>
|
||||||
|
public void SetCongestionControl(bool enable, bool adjustRate)
|
||||||
|
{
|
||||||
|
NormSetCongestionControl(_handle, enable, adjustRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the range of sender transmission rates within which the NORM congestion control algorithm is allowed to operate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rateMin">rateMin corresponds to the minimum transmission rate (bps).</param>
|
||||||
|
/// <param name="rateMax">rateMax corresponds to the maximum transmission rate (bps).</param>
|
||||||
|
public void SetTxRateBounds(double rateMin, double rateMax)
|
||||||
|
{
|
||||||
|
NormSetTxRateBounds(_handle, rateMin, rateMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets limits that define the number and total size of pending transmit objects a NORM sender will allow to be enqueued by the application.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sizeMax">The sizeMax parameter sets the maximum total size, in bytes, of enqueued objects allowed.</param>
|
||||||
|
/// <param name="countMin">The countMin parameter sets the minimum number of objects the application may enqueue, regardless of the objects' sizes and the sizeMax value.</param>
|
||||||
|
/// <param name="countMax">The countMax parameter sets a ceiling on how many objects may be enqueued, regardless of their total sizes with respect to the sizeMax setting.</param>
|
||||||
|
public void SetTxCacheBounds(long sizeMax, long countMin, long countMax)
|
||||||
|
{
|
||||||
|
NormSetTxCacheBounds(_handle,sizeMax, countMin, countMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The application's participation as a sender begins when this function is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sessionId">Application-defined value used as the instance_id field of NORM sender messages for the application's participation within a session.</param>
|
||||||
|
/// <param name="bufferSpace">This specifies the maximum memory space (in bytes) the NORM protocol engine is allowed to use to buffer any sender calculated FEC segments and repair state for the session.</param>
|
||||||
|
/// <param name="segmentSize">This parameter sets the maximum payload size (in bytes) of NORM sender messages (not including any NORM message header fields).</param>
|
||||||
|
/// <param name="blockSize">This parameter sets the number of source symbol segments (packets) per coding block, for the systematic Reed-Solomon FEC code used in the current NORM implementation.</param>
|
||||||
|
/// <param name="numParity">This parameter sets the maximum number of parity symbol segments (packets) the sender is willing to calculate per FEC coding block.</param>
|
||||||
|
/// <param name="fecId">Sets the NormFecType.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormStartSender() returns false, indicating the failure to start sender.</exception>
|
||||||
|
public void StartSender(int sessionId, long bufferSpace, int segmentSize, short blockSize, short numParity, NormFecType fecId)
|
||||||
|
{
|
||||||
|
if (!NormStartSender(_handle, sessionId, bufferSpace, segmentSize, blockSize, numParity, fecId))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to start sender");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The application's participation as a sender begins when this function is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sessionId">Application-defined value used as the instance_id field of NORM sender messages for the application's participation within a session.</param>
|
||||||
|
/// <param name="bufferSpace">This specifies the maximum memory space (in bytes) the NORM protocol engine is allowed to use to buffer any sender calculated FEC segments and repair state for the session.</param>
|
||||||
|
/// <param name="segmentSize">This parameter sets the maximum payload size (in bytes) of NORM sender messages (not including any NORM message header fields).</param>
|
||||||
|
/// <param name="blockSize">This parameter sets the number of source symbol segments (packets) per coding block, for the systematic Reed-Solomon FEC code used in the current NORM implementation.</param>
|
||||||
|
/// <param name="numParity">This parameter sets the maximum number of parity symbol segments (packets) the sender is willing to calculate per FEC coding block.</param>
|
||||||
|
/// <remarks>Uses NormFecType.RS for fecId.</remarks>
|
||||||
|
/// <exception cref="IOException">Thrown when NormStartSender() returns false, indicating the failure to start sender.</exception>
|
||||||
|
public void StartSender(int sessionId, long bufferSpace, int segmentSize, short blockSize, short numParity)
|
||||||
|
{
|
||||||
|
StartSender(sessionId, bufferSpace, segmentSize, blockSize, numParity, NormFecType.RS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The application's participation as a sender begins when this function is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bufferSpace">This specifies the maximum memory space (in bytes) the NORM protocol engine is allowed to use to buffer any sender calculated FEC segments and repair state for the session.</param>
|
||||||
|
/// <param name="segmentSize">This parameter sets the maximum payload size (in bytes) of NORM sender messages (not including any NORM message header fields).</param>
|
||||||
|
/// <param name="blockSize">This parameter sets the number of source symbol segments (packets) per coding block, for the systematic Reed-Solomon FEC code used in the current NORM implementation.</param>
|
||||||
|
/// <param name="numParity">This parameter sets the maximum number of parity symbol segments (packets) the sender is willing to calculate per FEC coding block.</param>
|
||||||
|
/// <param name="fecId">Sets the NormFecType.</param>
|
||||||
|
/// <remarks>Generates a random sessionId.</remarks>
|
||||||
|
/// <exception cref="IOException">Thrown when NormStartSender() returns false, indicating the failure to start sender.</exception>
|
||||||
|
public void StartSender(long bufferSpace, int segmentSize, short blockSize, short numParity, NormFecType fecId)
|
||||||
|
{
|
||||||
|
var sessionId = NormGetRandomSessionId();
|
||||||
|
StartSender(sessionId, bufferSpace, segmentSize, blockSize, numParity, fecId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The application's participation as a sender begins when this function is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bufferSpace">This specifies the maximum memory space (in bytes) the NORM protocol engine is allowed to use to buffer any sender calculated FEC segments and repair state for the session.</param>
|
||||||
|
/// <param name="segmentSize">This parameter sets the maximum payload size (in bytes) of NORM sender messages (not including any NORM message header fields).</param>
|
||||||
|
/// <param name="blockSize">This parameter sets the number of source symbol segments (packets) per coding block, for the systematic Reed-Solomon FEC code used in the current NORM implementation.</param>
|
||||||
|
/// <param name="numParity">This parameter sets the maximum number of parity symbol segments (packets) the sender is willing to calculate per FEC coding block.</param>
|
||||||
|
/// <remarks>Generates a random sessionId and uses NormFecType.RS for fecId.</remarks>
|
||||||
|
/// <exception cref="IOException">Thrown when NormStartSender() returns false, indicating the failure to start sender.</exception>
|
||||||
|
public void StartSender(long bufferSpace, int segmentSize, short blockSize, short numParity)
|
||||||
|
{
|
||||||
|
StartSender(bufferSpace, segmentSize, blockSize, numParity, NormFecType.RS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function terminates the application's participation in a NormSession as a sender. By default, the sender will
|
||||||
|
/// immediately exit the session without notifying the receiver set of its intention.
|
||||||
|
/// </summary>
|
||||||
|
public void StopSender()
|
||||||
|
{
|
||||||
|
NormStopSender(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function enqueues a file for transmission.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is an overload which will call FileEnqueue() with info set to encoding of the filename, infoOffset set to 0, and infoLength set to info.Length.
|
||||||
|
/// </reamarks>
|
||||||
|
/// <param name="filename">The fileName parameter specifies the path to the file to be transmitted. The NORM protocol engine
|
||||||
|
/// read and writes directly from/to file system storage for file transport, potentially providing for a very large virtual
|
||||||
|
/// "repair window" as needed for some applications. While relative paths with respect to the "current working directory"
|
||||||
|
/// may be used, it is recommended that full paths be used when possible.</param>
|
||||||
|
/// <returns>A NormFile is returned which the application may use in other NORM API calls as needed.</returns>
|
||||||
|
/// <exception cref="IOException">Thrown when NormFileEnqueue() returns NORM_OBJECT_INVALID, indicating the failure to enqueue file.</exception>
|
||||||
|
public NormFile FileEnqueue(string filename)
|
||||||
|
{
|
||||||
|
var info = Encoding.ASCII.GetBytes(filename);
|
||||||
|
return FileEnqueue(filename, info, 0, info.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function enqueues a file for transmission.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">The fileName parameter specifies the path to the file to be transmitted. The NORM protocol engine
|
||||||
|
/// read and writes directly from/to file system storage for file transport, potentially providing for a very large virtual
|
||||||
|
/// "repair window" as needed for some applications. While relative paths with respect to the "current working directory"
|
||||||
|
/// may be used, it is recommended that full paths be used when possible.</param>
|
||||||
|
/// <param name="info">The optional info and infoLength parameters are used to associate NORM_INFO content with the sent transport object.</param>
|
||||||
|
/// <param name="infoOffset">Indicates the strart of the message. Anything before it will not be sent.
|
||||||
|
/// Note: to send full message infoOffset should be set to 0.</param>
|
||||||
|
/// <param name="infoLength">The optional info and infoLength parameters are used to associate NORM_INFO content with the sent transport object.</param>
|
||||||
|
/// <returns>A NormFile is returned which the application may use in other NORM API calls as needed.</returns>
|
||||||
|
/// <exception cref="IOException">Thrown when NormFileEnqueue() returns NORM_OBJECT_INVALID, indicating the failure to enqueue file.</exception>
|
||||||
|
public NormFile FileEnqueue(string filename, byte[] info, int infoOffset, int infoLength)
|
||||||
|
{
|
||||||
|
byte[]? infoBytes;
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
infoBytes = info.Skip(infoOffset).Take(infoLength).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infoBytes = null;
|
||||||
|
infoLength = 0;
|
||||||
|
}
|
||||||
|
var objectHandle = NormFileEnqueue(_handle, filename, infoBytes, infoLength);
|
||||||
|
if (objectHandle == NormObject.NORM_OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to enqueue file");
|
||||||
|
}
|
||||||
|
return new NormFile(objectHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function enqueues a segment of application memory space for transmission.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is an overload which will call DataEnqueue() with info set to null, infoOffset set to 0, and infoLength set to 0.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="dataBuffer">The dataBuffer is a byte array containing the message to be transmitted.</param>
|
||||||
|
/// <param name="dataOffset">Indicates the strart of the message. Anything before it will not be sent.
|
||||||
|
/// Note: to send full message dataOffset should be set to 0.</param>
|
||||||
|
/// <param name="dataLength">Size of the message.</param>
|
||||||
|
/// <returns>A NormData is returned which the application may use in other NORM API calls as needed.</returns>
|
||||||
|
/// <exception cref="IOException">Thrown when NormDataEnqueue() returns NORM_OBJECT_INVALID, indicating the failure to enqueue data.</exception>
|
||||||
|
public NormData DataEnqueue(byte[] dataBuffer, int dataOffset, int dataLength)
|
||||||
|
{
|
||||||
|
return DataEnqueue(dataBuffer, dataOffset, dataLength, null, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function enqueues a segment of application memory space for transmission.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataBuffer">The dataBuffer is a byte array containing the message to be transmitted.</param>
|
||||||
|
/// <param name="dataOffset">Indicates the strart of the message. Anything before it will not be sent.
|
||||||
|
/// Note: to send full message dataOffset should be set to 0.</param>
|
||||||
|
/// <param name="dataLength">Size of the message.</param>
|
||||||
|
/// <param name="info">The optional info and infoLength parameters are used to associate NORM_INFO content with the sent transport object.</param>
|
||||||
|
/// <param name="infoOffset">Indicates the strart of the message.</param>
|
||||||
|
/// <param name="infoLength">The optional info and infoLength parameters are used to associate NORM_INFO content with the sent transport object.</param>
|
||||||
|
/// <returns>A NormData is returned which the application may use in other NORM API calls as needed.</returns>
|
||||||
|
/// <exception cref="IOException">Thrown when NormDataEnqueue() returns NORM_OBJECT_INVALID, indicating the failure to enqueue data.</exception>
|
||||||
|
public NormData DataEnqueue(byte[] dataBuffer, int dataOffset, int dataLength, byte[]? info, int infoOffset, int infoLength)
|
||||||
|
{
|
||||||
|
var dataBytes = dataBuffer.Skip(dataOffset).Take(dataLength).ToArray();
|
||||||
|
byte[]? infoBytes;
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
infoBytes = info.Skip(infoOffset).Take(infoLength).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infoBytes = null;
|
||||||
|
infoLength = 0;
|
||||||
|
}
|
||||||
|
var objectHandle = NormDataEnqueue(_handle, dataBytes, dataLength, infoBytes, infoLength);
|
||||||
|
if (objectHandle == NormObject.NORM_OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to enqueue data");
|
||||||
|
}
|
||||||
|
return new NormData(objectHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function opens a NORM_OBJECT_STREAM sender object and enqueues it for transmission.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// No data is sent until subsequent calls to StreamWrite() are made unless
|
||||||
|
/// NORM_INFO content is specified for the stream with the info and infoLength parameters. Example usage of
|
||||||
|
/// NORM_INFO content for NORM_OBJECT_STREAM might include application-defined data typing or other information
|
||||||
|
/// which will enable NORM receiver applications to properly interpret the received stream as it is being received.
|
||||||
|
/// This is an overload which will call StreamOpen() with info set to null, infoOffset set to 0, and infoLength set to 0.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="bufferSize">
|
||||||
|
/// The bufferSize parameter controls the size of the stream's "repair window"
|
||||||
|
/// which limits how far back the sender will "rewind" to satisfy receiver repair requests.
|
||||||
|
/// </param>
|
||||||
|
/// <returns> A NormStream is returned which the application may use in other NORM API calls as needed.</returns>
|
||||||
|
/// <exception cref="IOException">Thrown when NormStreamOpen() returns NORM_OBJECT_INVALID, indicating the failure to open stream.</exception>
|
||||||
|
public NormStream StreamOpen(long bufferSize)
|
||||||
|
{
|
||||||
|
return StreamOpen(bufferSize, null, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function opens a NORM_OBJECT_STREAM sender object and enqueues it for transmission.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// No data is sent until subsequent calls to NormStreamWrite() are made unless
|
||||||
|
/// NORM_INFO content is specified for the stream with the info and infoLength parameters. Example usage of
|
||||||
|
/// NORM_INFO content for NORM_OBJECT_STREAM might include application-defined data typing or other information
|
||||||
|
/// which will enable NORM receiver applications to properly interpret the received stream as it is being received.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="bufferSize"> The bufferSize parameter controls the size of the stream's "repair window"
|
||||||
|
/// which limits how far back the sender will "rewind" to satisfy receiver repair requests.</param>
|
||||||
|
/// <param name="info">Alloted memory space for transmitted information.</param>
|
||||||
|
/// <param name="infoOffset">Indicates the strart of the message. Anything before it will not be sent.
|
||||||
|
/// Note: to send full message infoOffset should be set to 0.</param>
|
||||||
|
/// <param name="infoLength">Size of the message.</param>
|
||||||
|
/// <returns>A NormStream is returned which the application may use in other NORM API calls as needed.</returns>
|
||||||
|
/// <exception cref="IOException">Thrown when NormStreamOpen() returns NORM_OBJECT_INVALID, indicating the failure to open stream.</exception>
|
||||||
|
public NormStream StreamOpen(long bufferSize, byte[]? info, int infoOffset, int infoLength)
|
||||||
|
{
|
||||||
|
byte[]? infoBytes;
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
infoBytes = info.Skip(infoOffset).Take(infoLength).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infoBytes = null;
|
||||||
|
infoLength = 0;
|
||||||
|
}
|
||||||
|
var objectHandle = NormStreamOpen(_handle, bufferSize, infoBytes, infoLength);
|
||||||
|
if (objectHandle == NormObject.NORM_OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to open stream");
|
||||||
|
}
|
||||||
|
return new NormStream(objectHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function initiates the application's participation as a receiver within the NormSession.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bufferSpace">The bufferSpace parameter is used to set a limit on the amount of bufferSpace allocated
|
||||||
|
/// by the receiver per active NormSender within the session.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormStartReceiver() returns false, indicating the failure to start receiver.</exception>
|
||||||
|
public void StartReceiver(long bufferSpace)
|
||||||
|
{
|
||||||
|
if(!NormStartReceiver(_handle, bufferSpace))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to start receiver");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function ends the application's participation as a receiver in the NormSession.
|
||||||
|
/// </summary>
|
||||||
|
public void StopReceiver()
|
||||||
|
{
|
||||||
|
NormStopReceiver(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the quantity of proactive "auto parity" NORM_DATA messages sent at the end of each FEC coding
|
||||||
|
/// block. By default (i.e., autoParity = 0), FEC content is sent only in response to repair requests (NACKs) from receivers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="autoParity">Setting a non-zero value for autoParity, the sender can automatically accompany each coding
|
||||||
|
/// block of transport object source data segments ((NORM_DATA messages) with the set number of FEC segments.</param>
|
||||||
|
public void SetAutoParity(short autoParity)
|
||||||
|
{
|
||||||
|
NormSetAutoParity(_handle, autoParity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the sender's maximum advertised GRTT value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="grttMax">The grttMax parameter, in units of seconds, limits the GRTT used by the group for scaling protocol timers, regardless
|
||||||
|
/// of larger measured round trip times. The default maximum for the NRL NORM library is 10 seconds.</param>
|
||||||
|
public void SetGrttMax(double grttMax)
|
||||||
|
{
|
||||||
|
NormSetGrttMax(_handle, grttMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the sender's mode of probing for round trip timing measurement responses from the receiver.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="probingMode">Possible values for the probingMode parameter include NORM_PROBE_NONE, NORM_PROBE_PASSIVE, and NORM_PROBE_ACTIVE.</param>
|
||||||
|
public void SetGrttProbingMode(NormProbingMode probingMode)
|
||||||
|
{
|
||||||
|
NormSetGrttProbingMode(_handle, probingMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function controls the sender GRTT measurement and estimation process.
|
||||||
|
/// The NORM sender multiplexes periodic transmission of NORM_CMD(CC) messages with its ongoing data transmission
|
||||||
|
/// or when data transmission is idle.When NORM congestion control operation is enabled, these probes are sent
|
||||||
|
/// once per RTT of the current limiting receiver(with respect to congestion control rate). In this case the intervalMin
|
||||||
|
/// and intervalMax parameters (in units of seconds) control the rate at which the sender's estimate of GRTT is updated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="intervalMin">At session start, the estimate is updated at intervalMin and the update interval time is doubled until intervalMax is reached.</param>
|
||||||
|
/// <param name="intervalMax">At session start, the estimate is updated at intervalMin and the update interval time is doubled until intervalMax is reached.</param>
|
||||||
|
public void SetGrttProbingInterval(double intervalMin, double intervalMax)
|
||||||
|
{
|
||||||
|
NormSetGrttProbingInterval(_handle, intervalMin, intervalMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the sender's "backoff factor".
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="backoffFactor">The backoffFactor (in units of seconds) is used to scale various timeouts related to the NACK repair process.</param>
|
||||||
|
public void SetBackoffFactor(double backoffFactor)
|
||||||
|
{
|
||||||
|
NormSetBackoffFactor(_handle, backoffFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the sender's estimate of receiver group size.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="groupSize">The sender advertises its groupSize setting to the receiver group in NORM protocol message
|
||||||
|
/// headers that, in turn, use this information to shape the distribution curve of their random timeouts for the timer-based,
|
||||||
|
/// probabilistic feedback suppression technique used in the NORM protocol.</param>
|
||||||
|
public void SetGroupSize(long groupSize)
|
||||||
|
{
|
||||||
|
NormSetGroupSize(_handle, groupSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This routine sets the "robustness factor" used for various NORM sender functions. These functions include the
|
||||||
|
/// number of repetitions of "robustly-transmitted" NORM sender commands such as NORM_CMD(FLUSH) or similar
|
||||||
|
/// application-defined commands, and the number of attempts that are made to collect positive acknowledgement
|
||||||
|
/// from receivers.These commands are distinct from the NORM reliable data transmission process, but play a role
|
||||||
|
/// in overall NORM protocol operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="txRobustFactor">The default txRobustFactor value is 20. This relatively large value makes
|
||||||
|
/// the NORM sender end-of-transmission flushing and positive acknowledgement collection functions somewhat immune from packet loss.
|
||||||
|
/// Setting txRobustFactor to a value of -1 makes the redundant transmission of these commands continue indefinitely until completion.</param>
|
||||||
|
public void SetTxRobustFactor(int txRobustFactor)
|
||||||
|
{
|
||||||
|
NormSetTxRobustFactor(_handle, txRobustFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function allows the application to resend (or reset transmission of) a NORM_OBJECT_FILE or NORM_OBJECT_DATA
|
||||||
|
/// transmit object that was previously enqueued for the session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="normObject">The normObject parameter must be a valid transmit NormObject that has not yet been "purged" from the sender's transmit queue.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormRequeueObject() returns false, indicating the failure to requeue object.</exception>
|
||||||
|
public void RequeueObject(NormObject normObject)
|
||||||
|
{
|
||||||
|
if(!NormRequeueObject(_handle, normObject.Handle))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to requeue object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function specifies a "watermark" transmission point at which NORM sender protocol operation should perform
|
||||||
|
/// a flushing process and/or positive acknowledgment collection for a given sessionHandle.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>This is an overload which will call the SetWatermark() override with overrideFlush set as false.</remarks>
|
||||||
|
/// <param name="normObject">The normObject parameter must be a valid transmit NormObject that has not yet been "purged" from the sender's transmit queue.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetWatermark() returns false, indicating the failure to set watermark.</exception>
|
||||||
|
public void SetWatermark(NormObject normObject)
|
||||||
|
{
|
||||||
|
SetWatermark(normObject, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function specifies a "watermark" transmission point at which NORM sender protocol operation should perform
|
||||||
|
/// a flushing process and/or positive acknowledgment collection for a given sessionHandle.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="normObject">The normObject parameter must be a valid transmit NormObject that has not yet been "purged" from the sender's transmit queue.</param>
|
||||||
|
/// <param name="overrideFlush">The optional overrideFlush parameter, when set to true, causes the watermark acknowledgment process that is
|
||||||
|
/// established with this function call to potentially fully supersede the usual NORM end-of-transmission flushing
|
||||||
|
/// process that occurs. If overrideFlush is set and the "watermark" transmission point corresponds to the last
|
||||||
|
/// transmission that will result from data enqueued by the sending application, then the watermark flush completion
|
||||||
|
/// will terminate the usual flushing process</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetWatermark() returns false, indicating the failure to set watermark.</exception>
|
||||||
|
public void SetWatermark(NormObject normObject, bool overrideFlush)
|
||||||
|
{
|
||||||
|
if(!NormSetWatermark(_handle, normObject.Handle, overrideFlush))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set watermark");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function cancels any "watermark" acknowledgement request that was previously set via the SetWatermark() function.
|
||||||
|
/// </summary>
|
||||||
|
public void CancelWatermark()
|
||||||
|
{
|
||||||
|
NormCancelWatermark(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <exception cref="IOException">Thrown when NormResetWatermark() returns false, indicating the failure to reset watermark.</exception>
|
||||||
|
public void ResetWatermark()
|
||||||
|
{
|
||||||
|
if(!NormResetWatermark(_handle))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to reset watermark");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When this function is called, the specified nodeId is added to the list of NormNodeId values (i.e., the "acking node"
|
||||||
|
/// list) used when NORM sender operation performs positive acknowledgement (ACK) collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeId">Identifies the application's presence in the NormSession.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormAddAckingNode() returns false, indicating the failure to add acking node.</exception>
|
||||||
|
public void AddAckingNode(long nodeId)
|
||||||
|
{
|
||||||
|
if(!NormAddAckingNode(_handle, nodeId))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to add acking node");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function deletes the specified nodeId from the list of NormNodeId values used when NORM sender operation
|
||||||
|
/// performs positive acknowledgement (ACK) collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeId">Identifies the application's presence in the NormSession.</param>
|
||||||
|
public void RemoveAckingNode(long nodeId)
|
||||||
|
{
|
||||||
|
NormRemoveAckingNode(_handle, nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function queries the status of the watermark flushing process and/or positive acknowledgment collection
|
||||||
|
/// initiated by a prior call to SetWatermark().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nodeId">Identifies the application's presence in the NormSession.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Possible return values include:
|
||||||
|
/// NORM_ACK_INVALID - The given sessionHandle is invalid or the given nodeId is not in the sender's acking list.
|
||||||
|
/// NORM_ACK_FAILURE - The positive acknowledgement collection process did not receive acknowledgment from every listed receiver (nodeId = NORM_NODE_ANY) or the identified nodeId did not respond.
|
||||||
|
/// NORM_ACK_PENDING - The flushing process at large has not yet completed (nodeId = NORM_NODE_ANY) or the given individual nodeId is still being queried for response.
|
||||||
|
/// NORM_ACK_SUCCESS - All receivers (nodeId = NORM_NODE_ANY) responded with positive acknowledgement or the given specific nodeId did acknowledge.
|
||||||
|
/// </returns>
|
||||||
|
public NormAckingStatus GetAckingStatus(long nodeId)
|
||||||
|
{
|
||||||
|
return NormGetAckingStatus(_handle, nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function enqueues a NORM application-defined command for transmission.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cmdBuffer">The cmdBuffer parameter points to a buffer containing the application-defined command content that will be contained in the NORM_CMD(APPLICA-TION) message payload.</param>
|
||||||
|
/// <param name="cmdLength">The cmdLength indicates the length of this content (in bytes) and MUST be less than or equal to the segmentLength value for the given session.</param>
|
||||||
|
/// <param name="robust">The command is NOT delivered reliably,
|
||||||
|
/// but can be optionally transmitted with repetition (once per GRTT) according to the NORM transmit robust factor
|
||||||
|
/// value for the given session if the robust parameter is set to true.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSendCommand() returns false, indicating the failure to send command.</exception>
|
||||||
|
public void SendCommand(byte[] cmdBuffer, int cmdLength, bool robust)
|
||||||
|
{
|
||||||
|
if(!NormSendCommand(_handle, cmdBuffer, cmdLength, robust))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to send command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function terminates any pending NORM_CMD(APPLICATION) transmission that was previously initiated with the SendCommand() call.
|
||||||
|
/// </summary>
|
||||||
|
public void CancelCommand()
|
||||||
|
{
|
||||||
|
NormCancelCommand(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets a limit on the number of outstanding (pending) NormObjects for which a receiver will keep state on a per-sender basis.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="countMax">The value countMax sets a limit on the maximum consecutive range of objects that can be pending.</param>
|
||||||
|
public void SetRxCacheLimit(int countMax)
|
||||||
|
{
|
||||||
|
NormSetRxCacheLimit(_handle, countMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function allows the application to set an alternative, non-default buffer size for the UDP socket for packet reception.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bufferSize">The bufferSize parameter specifies the socket buffer size in bytes.</param>
|
||||||
|
/// <exception cref="IOException">Thrown when NormSetRxSocketBuffer() returns false, indicating the failure to set rx socket buffer.</exception>
|
||||||
|
public void SetRxSocketBuffer(long bufferSize)
|
||||||
|
{
|
||||||
|
if(!NormSetRxSocketBuffer(_handle, bufferSize))
|
||||||
|
{
|
||||||
|
throw new IOException("Failed to set rx socket buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function provides the option to configure a NORM receiver application as a "silent receiver". This mode of
|
||||||
|
/// receiver operation dictates that the host does not generate any protocol messages while operating as a receiver.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="silent">Setting the silent parameter to true enables silent receiver operation while
|
||||||
|
/// setting it to false results in normal protocol operation where feedback is provided as needed for reliability and
|
||||||
|
/// protocol operation.</param>
|
||||||
|
/// <param name="maxDelay">When the maxDelay parameter is set to a non-negative value, the value determines the maximum number
|
||||||
|
/// of FEC coding blocks (according to a NORM sender's current transmit position) the receiver will cache an incompletely-received
|
||||||
|
/// FEC block before giving the application the (incomplete) set of received source segments.</param>
|
||||||
|
public void SetSilentReceiver(bool silent, int maxDelay)
|
||||||
|
{
|
||||||
|
NormSetSilentReceiver(_handle, silent, maxDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function controls the default behavior determining the destination of receiver feedback messages generated
|
||||||
|
/// while participating in the session.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enable">If the enable parameter is true, "unicast NACKing" is enabled for new remote
|
||||||
|
/// senders while it is disabled for state equal to false.</param>
|
||||||
|
public void SetDefaultUnicastNack(bool enable)
|
||||||
|
{
|
||||||
|
NormSetDefaultUnicastNack(_handle, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the default "synchronization policy" used when beginning (or restarting) reception of objects
|
||||||
|
/// from a remote sender (i.e., "syncing" to the sender).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="syncPolicy">The "synchronization policy" is the behavior observed by the receiver with regards to what objects it attempts to reliably receive
|
||||||
|
/// (via transmissions of Negative Acknowledgements to the sender(s) or group as needed).</param>
|
||||||
|
public void SetDefaultSyncPolicy(NormSyncPolicy syncPolicy)
|
||||||
|
{
|
||||||
|
NormSetDefaultSyncPolicy(_handle, syncPolicy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function sets the default "nacking mode" used when receiving objects.
|
||||||
|
/// This allows the receiver application some control of its degree of participation in the repair process. By limiting receivers
|
||||||
|
/// to only request repair of objects in which they are really interested in receiving, some overall savings in unnecessary
|
||||||
|
/// network loading might be realized for some applications and users.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nackingMode">Specifies the nacking mode.</param>
|
||||||
|
public void SetDefaultNackingMode(NormNackingMode nackingMode)
|
||||||
|
{
|
||||||
|
NormSetDefaultNackingMode(_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 SetDefaultRepairBoundary(NormRepairBoundary repairBoundary)
|
||||||
|
{
|
||||||
|
NormSetDefaultRepairBoundary(_handle, repairBoundary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This routine controls how persistently NORM receivers will maintain state for sender(s) and continue to request
|
||||||
|
/// repairs from the sender(s) even when packet reception has ceased.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rxRobustFactor">The rxRobustFactor 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 SetDefaultRxRobustFactor(int rxRobustFactor)
|
||||||
|
{
|
||||||
|
NormSetDefaultRxRobustFactor(_handle, rxRobustFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
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>
|
||||||
|
public int Write(byte[] buffer, int offset, int length)
|
||||||
|
{
|
||||||
|
var bytes = buffer.Skip(offset).Take(length).ToArray();
|
||||||
|
return NormStreamWrite(_handle, bytes, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 a default function which calls Flush(bool eom, NormFlushMode flushMode) override
|
||||||
|
/// 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 a default function which calls Close(bool graceful) override
|
||||||
|
/// 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>
|
||||||
|
public int Read(byte[] buffer, int offset, int length)
|
||||||
|
{
|
||||||
|
var bytes = new byte[length];
|
||||||
|
|
||||||
|
if (!NormStreamRead(_handle, bytes, ref length))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
var bufferPosition = offset + i;
|
||||||
|
if (bufferPosition < buffer.Length)
|
||||||
|
{
|
||||||
|
buffer[bufferPosition] = bytes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,261 @@
|
||||||
|
using Bogus;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
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);
|
||||||
|
_normSession.DataEnqueue(data, 0, data.Length);
|
||||||
|
|
||||||
|
Assert.True(_normInstance.HasNextEvent(TimeSpan.FromSeconds(1.5)));
|
||||||
|
|
||||||
|
_normSession.StopSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
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);
|
||||||
|
_normSession.DataEnqueue(data, 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