.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
|
||||
*.a
|
||||
|
||||
# build java files
|
||||
*.class
|
||||
|
||||
#build android files
|
||||
android/.gradle
|
||||
|
||||
# waf cruft
|
||||
.waf*
|
||||
.lock-waf*
|
||||
waf*/*
|
||||
|
||||
# OS generated files #
|
||||
.DS_Store
|
||||
|
|
@ -30,3 +37,272 @@ norp/makefiles/norp
|
|||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
*.sqlite
|
||||
*.sqlite-shm
|
||||
*.sqlite-wal
|
||||
|
||||
# Nuget files
|
||||
DeploymentSettings.props
|
||||
Directory.Build.props
|
||||
Directory.Build.targets
|
||||
Packages.props
|
||||
|
||||
#Local Log Files
|
||||
log*.txt
|
||||
|
|
|
|||
|
|
@ -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
|
||||
enum NormNackingMode {
|
||||
ORM_NACK_NONE
|
||||
NORM_NACK_NONE
|
||||
NORM_NACK_INFO_ONLY
|
||||
NORM_NACK_NORMAL
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,15 @@ class NormInputStream {
|
|||
+ Read() : int
|
||||
+ <<override>> Read(buffer:byte[], offset:int, length:int) : int
|
||||
- ProcessEvent() : void
|
||||
+ <<override>> Flush() : void
|
||||
+ <<override>> Write(buffer:byte[], offset:int, count:int) : void
|
||||
+ <<override>> Seek(offset:long, origin:SeekOrigin) : long
|
||||
+ <<override>> SetLength(value:long) : void
|
||||
+ <<override>> CanRead : bool <<get>>
|
||||
+ <<override>> CanSeek : bool <<get>>
|
||||
+ <<override>> CanWrite : bool <<get>>
|
||||
+ <<override>> Length : long <<get>>
|
||||
+ <<override>> Position : long <<get>> <<set>>
|
||||
}
|
||||
Stream <|-- NormInputStream
|
||||
@enduml
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class NormOutputStream {
|
|||
+ SetTtl(ttl:byte) : void
|
||||
+ SetTos(tos:byte) : void
|
||||
+ SetCongestionControl(ccEnabled:bool, ccAdjustRate: bool) : void
|
||||
+ SetTxRateBounds(rateMin:double, rateMax:double) : void
|
||||
+ SetTxRateBounds(minTxRate:double, maxTxRate:double) : void
|
||||
+ TxRate:double <<get>> <<set>>
|
||||
+ GrttEstimate:double <<get>> <<set>>
|
||||
+ SetGroupSize(groupSize:long) : void
|
||||
|
|
@ -30,11 +30,20 @@ class NormOutputStream {
|
|||
+ RemoveNormEventListener(normEventListener:INormEventListener): void
|
||||
- FireNormEventOccured(normEvent:NormEvent) : void
|
||||
+ Open(sessionId:int, bufferSpace:long, segmentSize:int, blockSize:short, numParity:short, repairWindow:long) : void
|
||||
+ <<override>> Dispose() : void
|
||||
+ <<override>> Close() : void
|
||||
+ IsClosed : bool <<get>>
|
||||
+ Write(b:int) : void
|
||||
+ <<override>> Write(buffer:byte[], offset:int, count:int)
|
||||
- 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
|
||||
@enduml
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
@startuml
|
||||
struct NormEvent
|
||||
{
|
||||
+ Type : NormEventType
|
||||
+ Session : long
|
||||
+ Sender : long
|
||||
+ Object : long
|
||||
}
|
||||
class NormApi
|
||||
{
|
||||
+ <<const>> NORM_OBJECT_INVALID : int = 0
|
||||
+ <<const>> FILENAME_MAX : int = 260
|
||||
+ <<const>> NORM_LIBRARY : string = "norm"
|
||||
+ {static} NormGetVersion(major:int, minor:int, patch:int) : int
|
||||
+ {static} NormCreateInstance() : long
|
||||
+ {static} NormCreateInstance(priorityBoost:bool) : long
|
||||
+ {static} NormDestroyInstance(instanceHandle:long) : void
|
||||
+ {static} NormStopInstance(instanceHandle:long) : void
|
||||
|
|
@ -13,63 +16,36 @@ class NormApi
|
|||
+ {static} NormSuspendInstance(instanceHandle:long) : bool
|
||||
+ {static} NormResumeInstance(instanceHandle:long) : void
|
||||
+ {static} NormSetCacheDirectory(instanceHandle:long, cachePath:string) : bool
|
||||
+ {static} NormGetNextEvent(instanceHandle:long, theEvent:NormEvent) : 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} 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} NormGetAddress(sessionHandle:long, addrBuffer:string, bufferLen:uint) : 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} NormSetTxPort(sessionHandle:long, txPortNumber:int, enableReuse:bool, txBindAddress:string) : bool
|
||||
+ {static} NormSetTxOnly(sessionHandle:long, txOnly:bool, connectToSessionAddress:bool) : void
|
||||
+ {static} NormLimitObjectInfo(sessionHandle:long, state:bool) : 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} NormSetRxPortReuse(sessionHandle:long, enableReuse:bool, rxBindAddress:string, senderAddress:string, senderPort:int) : void
|
||||
+ {static} NormSetEcnSupport(sessionHandle:long, ecnEnable:bool, ignoreLoss:bool, tolerateLoss:bool) : void
|
||||
+ {static} NormSetMulticastInterface(sessionHandle:long, interfaceName:string) : bool
|
||||
+ {static} NormSetSSM(sessionHandle:long, sourceAddress:string) : bool
|
||||
+ {static} NormSetTTL(sessionHandle:long, ttl:byte) : bool
|
||||
+ {static} NormSetTOS(sessionHandle:long, tos:byte) : 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} NormSetTxLoss(sessionHandle:long, precent:double) : void
|
||||
+ {static} NormSetRxLoss(sessionHandle:long, precent:double) : void
|
||||
+ {static} NormOpenDebugLog(instanceHandle:long, path:string) : bool
|
||||
+ {static} NormCloseDebugLog(instanceHandle:long) : void
|
||||
+ {static} NormOpenDebugPipe(instanceHandle:long, pipeName:string) : bool
|
||||
+ {static} NormCloseDebugPipe(instanceHandle:long) : void
|
||||
+ {static} NormSetDebugLevel(level:int) : void
|
||||
+ {static} NormGetDebugLevel() : int
|
||||
+ {static} NormSetReportInterval(sessionHandle:long, interval:double) : void
|
||||
+ {static} NormGetReportInterval(sessionHandle:long) : double
|
||||
+ {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} NormStopSender(sessionHandle:long) : void
|
||||
+ {static} NormSetTxRate(sessionHandle:long, bitsPerSecond:double) : void
|
||||
+ {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} NormSetCongestionControl(sessionHandle:long, enable:bool) : void
|
||||
+ {static} NormSetCongestionControl(sessionHandle:long, enable:bool, adjustRate:bool) : void
|
||||
+ {static} NormSetTxRateBounds(sessionHandle:long, rateMin:double, rateMax:double) : 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} NormSetGrttProbingMode(sessionHandle:long, probingMode:NormProbingMode) : 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} NormSetGroupSize(sessionHandle:long, groupSize:uint) : void
|
||||
+ {static} NormSetGroupSize(sessionHandle:long, groupSize:long) : 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} NormDataEnqueue(sessionHandle:long, dataPtr:string, dataLen:int) : long
|
||||
+ {static} NormDataEnqueue(sessionHandle:long, dataPtr:string, dataLen:int, infoPtr:string, infoLen:int) : long
|
||||
+ {static} NormDataEnqueue(sessionHandle:long, dataPtr:byte[], dataLen:int, infoPtr:byte[], infoLen:int) : long
|
||||
+ {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} NormStreamClose(streamHandle:long) : void
|
||||
+ {static} NormStreamClose(streamHandle:long, graceful:bool) : void
|
||||
+ {static} NormGetStreamBufferSegmentCount(bufferBytes:uint, segmentSize:ushort, blockSize:ushort) : uint
|
||||
+ {static} NormStreamWrite(streamHandle:long, buffer:string, numBytes:uint) : uint
|
||||
+ {static} NormStreamFlush(streamHandle:long) : void
|
||||
+ {static} NormStreamWrite(streamHandle:long, buffer:byte[], numBytes:int) : int
|
||||
+ {static} NormStreamFlush(streamHandle:long, eom:bool, flushMode:NormFlushMode) : void
|
||||
+ {static} NormStreamSetAutoFlush(streamHandle:long, flushMode: NormFlushMode) : void
|
||||
+ {static} NormStreamSetPushEnable(streamHandle:long, pushEnable:bool) : void
|
||||
+ {static} NormStreamHasVacancy(streamHandle:long) : bool
|
||||
+ {static} NormStreamGetVacancy(streamHandle:long, bytesWanted:uint) : uint
|
||||
+ {static} NormStreamMarkEom(streamHandle:long) : void
|
||||
+ {static} NormSetWatermark(sessionHandle:long, objectHandle:long) : 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} NormCancelWatermark(sessionHandle:long) : void
|
||||
+ {static} NormAddAckingNode(sessionHandle:long, nodeId:long) : bool
|
||||
+ {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} NormGetNextAckingNode(sessionHandle:long, nodeId:long) : 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} NormSendCommand(sessionHandle:long, cmdBuffer:byte[], cmdLength:int, robust:bool) : bool
|
||||
+ {static} NormCancelCommand(sessionHandle:long) : void
|
||||
+ {static} NormSetSynStatus(sessionHandle:long, state:bool) : void
|
||||
+ {static} NormStartReceiver(sessionHandle:long, bufferSpace:long) : bool
|
||||
+ {static} NormStopReceiver(sessionHandle:long) : void
|
||||
+ {static} NormSetRxCacheLimit(sessionHandle:long, countMax:ushort) : void
|
||||
+ {static} NormSetRxSocketBuffer(sessionHandle:long, bufferSize:uint) : bool
|
||||
+ {static} NormSetSilentReceiver(sessionHandle:long, silent:bool) : void
|
||||
+ {static} NormSetRxCacheLimit(sessionHandle:long, countMax:int) : void
|
||||
+ {static} NormSetRxSocketBuffer(sessionHandle:long, bufferSize:long) : bool
|
||||
+ {static} NormSetSilentReceiver(sessionHandle:long, silent:bool, maxDelay:int) : void
|
||||
+ {static} NormSetDefaultUnicastNack(sessionHandle: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} NormNodeSetRepairBoundary(remoteSender:long, repairBoundary:NormRepairBoundary) : void
|
||||
+ {static} NormSetDefaultRxRobustFactor(sessionHandle:long, robustFactor:int) : void
|
||||
+ {static} NormNodeSetRxRobustFactor(remoteSenderremoteSender, robustFactor:int) : void
|
||||
+ {static} NormPreallocateRemoteSender(sessionHandle:long, bufferSize:ulong, segmentSize:ushort, numData:ushort, numParity:ushort) : 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} NormNodeSetRxRobustFactor(remoteSender:long, robustFactor:int) : void
|
||||
+ {static} NormStreamRead(streamHandle:long, buffer:byte[], numBytes:int) : bool
|
||||
+ {static} NormStreamSeekMsgStart(streamHandle:long) : bool
|
||||
+ {static} NormStreamGetReadOffset(streamHandle:long) : uint
|
||||
+ {static} NormStreamGetBufferUsage(streamHandle:long) : uint
|
||||
+ {static} NormStreamGetReadOffset(streamHandle:long) : long
|
||||
+ {static} NormObjectGetType(objectHandle:long) : NormObjectType
|
||||
+ {static} NormObjectHasInfo(objectHandle:long) : bool
|
||||
+ {static} NormObjectGetInfoLength(objectHandle:long) : ushort
|
||||
+ {static} NormObjectGetInfo(objectHandle:long, buffer:char, bufferLen:ushort) : ushort
|
||||
+ {static} NormObjectGetInfoLength(objectHandle:long) : int
|
||||
+ {static} NormObjectGetInfo(objectHandle:long, buffer:byte[], bufferLen:int) : int
|
||||
+ {static} NormObjectGetSize(objectHandle:long) : int
|
||||
+ {static} NormObjectGetBytesPending(objectHandle:long) : int
|
||||
+ {static} NormObjectCancel(objectHandle:long) : void
|
||||
|
|
@ -153,24 +106,14 @@ class NormApi
|
|||
+ {static} NormObjectRelease(objectHandle:long) : void
|
||||
+ {static} NormFileGetName(fileHandle:long, nameBuffer:string, bufferLen:int) : bool
|
||||
+ {static} NormFileRename(fileHandle:long, fileName:string) : bool
|
||||
+ {static} NormDataAccessData(objectHandle:long) : string
|
||||
+ {static} NormDataDetachData(objectHandle:long) : string
|
||||
+ {static} NormDataAccessData(objectHandle:long) : nint
|
||||
+ {static} NormObjectGetSender(objectHandle:long) : long
|
||||
+ {static} NormNodeGetId(nodeHandle:long) : uint
|
||||
+ {static} NormNodeGetAddress(nodeHandle:long, addrBuffer:string, bufferLen: uint) : bool
|
||||
+ {static} NormNodeGetAddress(nodeHandle:long, addrBuffer:string, bufferLen: uint, port:ushort) : bool
|
||||
+ {static} NormNodeGetId(nodeHandle:long) : long
|
||||
+ {static} NormNodeGetAddress(nodeHandle:long, addrBuffer:byte[], bufferLen: int, port:int) : bool
|
||||
+ {static} NormNodeGetGrtt(remoteSender:long) : double
|
||||
+ {static} NormNodeGetCommand(remoteSender:long, :string, buflen:uint) : bool
|
||||
+ {static} NormNodeSendAckEx(remoteSender:long, buffer:string, numBytes:uint) : bool
|
||||
+ {static} NormNodeGetWatermarkEx(remoteSender:long, buffer:string, buflen:uint) : bool
|
||||
+ {static} NormNodeGetCommand(remoteSender:long, buffer:byte[], buflen:int) : bool
|
||||
+ {static} NormNodeFreeBuffers(remoteSender:long) : void
|
||||
+ {static} NormNodeDelete(remoteSender:long) : void
|
||||
+ {static} NormNodeRetain(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
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
@startuml
|
||||
class NormFile {
|
||||
+ <<const>> FILENAME_MAX : int = 260
|
||||
~ NormFile(handle:long)
|
||||
+ Name : string <<get>>
|
||||
+ Rename(filename:string) : void
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
@startuml
|
||||
class NormInstance {
|
||||
+ <<const>> NORM_DESCRIPTOR_INVALID : int = 0
|
||||
- _handle: long
|
||||
+ NormInstance()
|
||||
+ NormInstance(priorityBoost:bool)
|
||||
|
|
@ -14,7 +15,9 @@ class NormInstance {
|
|||
+ CloseDebugLog() : void
|
||||
+ OpenDebugPipe(pipename:string) : void
|
||||
+ 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
|
||||
+ CreateSession(address:string, port:int, localNodeId:long) : NormSession
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
@startuml
|
||||
class NormNode {
|
||||
+ <<const>> NORM_NODE_ANY : long = 0xffffffff
|
||||
+ <<const>> NORM_NODE_NONE : int = 0
|
||||
+ <<const>> NORM_NODE_INVALID : int = 0
|
||||
- _handle : long
|
||||
~ NormNode(handle:long)
|
||||
+ SetUnicastNack(state:bool) : void
|
||||
|
|
@ -8,9 +10,9 @@ class NormNode {
|
|||
+ SetRepairBoundary(repairBoundary:NormRepairBoundary) : void
|
||||
+ SetRxRobustFactor(robustFactor:int) : void
|
||||
+ Id : long <<get>>
|
||||
+ Address : SocketAddress <<get>>
|
||||
+ Address : IPEndPoint <<get>>
|
||||
+ Grtt : double <<get>>
|
||||
+ GetCommand(buffer:byte[], offset:int, length:int) : int
|
||||
+ Command : byte[] <<get>>
|
||||
+ FreeBuffers() : void
|
||||
+ Retain() : void
|
||||
+ Release(): void
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
@startuml
|
||||
class NormObject {
|
||||
+ <<const>> NORM_OBJECT_INVALID : int = 0
|
||||
# _handle:long
|
||||
~ NormObject(handle:long)
|
||||
+ SetNackingMode(nackingMode:NormNackingMode) : void
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
@startuml
|
||||
class NormSession {
|
||||
+ <<const>> NORM_SESSION_INVALID : int = 0
|
||||
{static} -_normSessions : Dictionary<long, NormSession>
|
||||
- _handle : long
|
||||
~ NormSession(handle:long)
|
||||
|
|
@ -22,8 +23,10 @@ class NormSession {
|
|||
+ SetTxLoss(precent:double) : void
|
||||
+ SetRxLoss(precent:double) : void
|
||||
+ 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) : 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
|
||||
+ SetTxOnly(txOnly:bool) : void
|
||||
+ TxRate:double <<get>> <<set>>
|
||||
|
|
@ -43,11 +46,12 @@ class NormSession {
|
|||
+ SetTxRobustFactor(robustFactor:int) : void
|
||||
+ FileEnqueue(filename:string) : NormFile
|
||||
+ FileEnqueue(filename:string, info:byte[], infoOffset:int, infoLength:int) : NormFile
|
||||
+ DataEnqueue(dataBuffer:MemoryStream, dataOffset:int, dataLength:int) : NormData
|
||||
+ DataEnqueue(dataBuffer:MemoryStream, dataOffset:int, dataLength:int, info:byte[], infoOffset:int, infoLength:int) : NormData
|
||||
+ DataEnqueue(dataBuffer:byte[], dataLength:int) : NormData
|
||||
+ DataEnqueue(dataBuffer:byte[], dataOffset:int, dataLength:int, info:byte[], infoOffset:int, infoLength:int) : NormData
|
||||
+ RequeueObject(object:NormObject) : void
|
||||
+ StreamOpen(bufferSize:long) : NormStream
|
||||
+ StreamOpen(bufferSize:long, info:byte[], infoOffset:int, infoLength:int) : NormStream
|
||||
+ SetWatermark(object:NormObject) : void
|
||||
+ SetWatermark(object:NormObject, overrideFlush:bool) : void
|
||||
+ CancelWatermark() : void
|
||||
+ ResetWatermark() : void
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ class NormStream {
|
|||
+ SeekMsgStart() : bool
|
||||
+ ReadOffset : long <<get>>
|
||||
}
|
||||
NormObject <|-- NormStream
|
||||
@enduml
|
||||
|
|
@ -7,7 +7,7 @@ Client <- NormInstance : NormInstance
|
|||
Client -> NormInstance : CreateSession(address, port, localNodeId)
|
||||
NormInstance -> NormApi : NormCreateSession(instanceHandle, address, port, localNodeId)
|
||||
NormInstance <- NormApi : sessionHandle
|
||||
alt sessionHandle == NORM_SESSION_INVALID
|
||||
alt sessionHandle == NormApi.NORM_SESSION_INVALID
|
||||
NormInstance -> IOException : throw new("Failed to create session")
|
||||
end
|
||||
NormInstance -> NormSession : new(sessionHandle)
|
||||
|
|
@ -30,9 +30,9 @@ end
|
|||
NormSession -> NormFile: new(objectHandle)
|
||||
NormSession <- NormFile : NormFile
|
||||
Client <- NormSession : NormFile
|
||||
loop NormEvent != null
|
||||
Client -> NormInstance : GetNextEvent()
|
||||
NormInstance -> NormApi : NormGetNextEvent(instanceHandle, NormEvent)
|
||||
loop NormInstance.HasNextEvent(waitTime)
|
||||
Client -> NormInstance : GetNextEvent(false)
|
||||
NormInstance -> NormApi : NormGetNextEvent(instanceHandle, NormEvent, false)
|
||||
NormInstance <- NormApi : success
|
||||
alt success == false
|
||||
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