Compare commits

..

124 Commits

Author SHA1 Message Date
Joe Calderon 1686404314
fix ci builds by pinning msvc to windows-2022 and configuring waf on linux (#103) 2026-07-08 09:29:06 -04:00
Joe Calderon 75a3dd59ee
Some safety fixes (#101)
* Fix uninitialized memory read vulnerability in packet validation

* Fix buffer overflows in temporary file generation
2026-07-03 12:01:20 -04:00
dependabot[bot] d6b4695c4c
Bump rand from 0.8.5 to 0.8.6 in /src/rust (#100)
Bumps [rand](https://github.com/rust-random/rand) from 0.8.5 to 0.8.6.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/0.8.6/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.8.5...0.8.6)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.8.6
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-23 22:25:12 -04:00
bebopagogo 0c4b130c7b fixed NormCmdCCMsg item parsing and iteration per issue reported by CrunchyJohnHaven 2026-05-23 20:48:17 -04:00
Caleb fcd2554051
Add rust bindings (#98)
* add rust bindings to norm

* modify PR description

* remove PR description since it is redundant

* remove weird character

* remove __pycache__ and add __pycache__ to gitignore

---------

Co-authored-by: cbowers <cbowers@anduril.com>
2026-05-23 20:25:32 -04:00
Fabrice Fontaine b0c38b4184
wscript: fix build with waf >= 2.1.0 (#86)
Replace add_option_group by add_argument_group to a build failure with
waf 2.1.0 and
bd5c22d484:

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2026-03-12 11:23:09 -04:00
Jeffery Weston 823e3e8c88 fix npc compilation error 2025-07-23 13:32:38 -04:00
bebopagogo f3a60510ff Merge branch 'master' of https://github.com/USNavalResearchLaboratory/norm
merging remote changes
2025-04-23 09:52:33 -04:00
bebopagogo 6a2da08d86 edits 2025-04-23 09:50:08 -04:00
bebopagogo 9500578e89 Merge branch 'master' of https://github.com/USNavalResearchLaboratory/norm
Incorporation of formatting tweaks with primary code.
2025-04-22 16:16:04 -04:00
bebopagogo 3802edadf1 minor formatting tweak 2025-04-22 16:15:58 -04:00
Jeff Weston 1c534c05f1
Remove debug lines
Removed debug lines added in bc6e81f to fix #94
2025-03-31 10:52:48 -04:00
mullerj 4fd768f9cc
.NET NORM Extension (#85)
* .NET Extension Design (#5)

* Designed .NET classes from Java

Co-authored-by: Sergiy <sergiy.yermak.ctr@us.navy.mil>

* Added NormApi static class

* Started on api uml

Co-authored-by: mullerj <mullerj@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>

* Add static methods to api uml

* add static method to normapi uml

* Add enums

* Changes

* Overload methods with defaults

* type marshalling

* change handles to in nuint

* marshall more handles

* Removed in/ref and reformatted.

Co-authored-by: mullerj <mullerj@users.noreply.github.com>

* Removed duplicate enums

* Removed NormEvent from NormApi

* Fixed typo

* design NormInstance methods

Co-authored-by: mullerj <mullerj@users.noreply.github.com>

* Fixed CreateInstance method

* Changed handles to long

* Change id types to long

* Remove condition checks that do nothing

* Removed UserData functions

* Removed NormAlloc() and NormFree()

* Cleaned up some API methods

* Fix misspelling

Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>

* Design NormSession methods

Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>

* Added missing comma

* Uml for enqueue
Co-authored-by: mullerj <mullerj@users.noreply.github.com>

* Updated design based on enqueue test

* Updated EnqueueFile sequence diagram

Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>

* Moved sequence diagrams

* Added constants to NormApi

* Removed method level sequence diagrams

---------

Co-authored-by: Sergiy <sergiy.yermak.ctr@us.navy.mil>
Co-authored-by: syermak <syerm001@odu.edu>
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>
Co-authored-by: Sergiy <47069243+SergiyYermak@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfreeman3@gmail.com>

* .NET Extension Design Implementation (#10)

* changes

* Removed GetsNextEvent test

* Implemented GetNextEvent

* Fixed NormStream design

* Fixed HasNextEvent design

* Added NormGetNextEvent overload

* Implemented HasNextEvent

* Updated design

* Added Kernel32 to design

* Modified to use .NET EventWaitHandle instead of kernel32 P/Invoke

* Modified to only copy norm.dll on Windows

* Added copy for non Windows

* add start and stop receiver

* add receiver

* Modified non-Windows to use Socket for HasNextEvent

* Deleted NormFileTests since they break the other tests

* Fixed ReceiverReceives test

* Updated ReceiverReceives test name

* Modified ReceivesFile to get all events instead of adding to array

* Cleaned up NormInstance formatting

* Refactored tests

* Updated NormFile

* Implemented send stream

* Implemented receive stream

* Implemented NormFile Name

* Updated ReceivesFile to use events

* data enqueue

* Fixed merge

* Fixed ReceivesData test

* Modified data test to compare collections without order

* stop instance working

* enqueues data

* Reverted upgrade to .NET 7

* Restartinstance is working

* Modified NormData to read bytes instead of as string

* Removed using statements in NormData

* Updated design

* Updated design

* Switched to nint

* Switched design to nint

* unfinished test for suspendinstance

* working suspend instance

* added resume function to instance

* Updated session send and receive data tests

* Removed launch settings

* session configuration functions

* Modified to use random port due to intermittent failed tests due to session conflict

* Modified to randomize text content

* Implemented NormNode Address

* Updated design for NormNode

* Implemented NormNode Grtt

* Implemented NormNode Id

* implement session configuration functions

* instance

* missing return types

* add missing handle param

* normNode

* Implemented RequeueObject

* Implemented SetWatermark and AckingNode

* Implemented CancelWatermark

* Implemented ResetWatermark

* Implemented SendCommand

* Implemented CancelCommand

* Implemented DebugLevel. Removed DebugPipe

* Updated SetTxPort

* Updated SetRxPortReuse

* Implemented SetEcnSupport

* Added test for RxLoss

* Implemented ReportInterval

* Refactored session calculated properties

* Updated enqueue methods

* Updated StreamOpen design

* Fixed SetWatermark overload

* Implemented GetAckingStatus

* Removed SendCommand overload

* Removed SetSilentReceiver overload

* Implemented NormEvent ToString

* Implemented NormFile Rename

* Implemented SetUnicastNack

* Added ReceivesCommand test

* Implemented SetNackingMode

* Implemented SetRepairBoundary

* Added Fact to SetsRepairBoundary test

* Implemented SetRxRobustFactor

* Implemented NormNode Command

* Implemented FreeBuffers

* Implemented Retain and Release

* Fix using namespaces

* test get object type

* NormObject get size

* NormObject setNackingMode

* NormObject get bytes pending

* NormObjet cancel

* NormObject retain

* NormObject release

* NormObject get sender

* NormObject get hashcode

* normObject equals

* Implemented NormObject Equals

* Removed redundant cast

* Removed unused using directive

* Removed static using

* Added NormApi to global Usings

* Added Enums to global usings

* Cleaned up NormObject Equals

* Cleaned up NormObject GetHashCode() test

* Cleaned up warning

* normStream has vacancy

* normStream read offset

* normStream seek msg start

* NormEventListener interface

* normStream set push enable

* normStream set auto flush

* Simplified NormApi usage

* Updated design of NormStream

* public interface

* Fixed INormEventListener

* fixing name space

* commit initializing  inputstream

* Added StreamBreakException

* Fixed formatting

* Fixed formatting

* Fixed formatting

* Initial implementation of NormOutputStream

* Cleaned up NormObject Equals

* NormInputStream class

Co-authored-by: mullerj <mullerj@users.noreply.github.com>

* normStream data offset

* move offset length arithmetic into write method

* building normInputstream

* all method implemented

Co-authored-by: mullerj <mullerj@users.noreply.github.com>

* NormStreamRead

* Fixed build error

* Completed ReceivesStreamWithOffset test

* Added retries to GetsCommand test

* Updated type for NormStreamRead

* Simplified NormStream Read

* Simplified NormStream Write

* Added dataOffset to DataEnqueue

* Fixed DataEnqueue overload

* Added infoOffset to FileEnqueue

* Added infoOffset to StreamOpen

* Updated design

* Removed extra overload of FileEnqueue

* Removed DataEnqueue overloads

* Removed extra overload from StreamOpen

* Added HasNextEvent overload

* Implemented OpenDebugPipe

* add thread locking

* locking for properties

* Not supported exceptions

* Implementing sychronize

* fixing inputstream

* adding sychronize message

* Reorganized NormApi and updated design

* Modified to skip GetsCommand test on IO exception

* WIP: 537b706 adding sychronize message

* adding message to expections

* Fixed test file cleanup

* Added locking to NormSession methods that use static field

* Changed StartsSender to skippablefact

* Changed to SetsNackingMode to skippable fact

* Converted tests to skippable

* Converted more tests to skippable

* Converted all tests that start sender to skippable

* Updated README about skipped tests

* documentation

* 2 doc

* Cleaned up input and output stream classes

* Cleaned up NormApi

* Updated NormOutputStream Write

* Added document comments to NormApi

* Added comments to NormApi

* Removed unnecessary usings

* Added comments to NormApi

* set up the rest of doc

* api documentation

* fix typo

* fix spacing

* Doc for instance need clean up

* clean up

* document norm session

* NormStream documentation

* commit for node

* NormObject docs

* Updated NormApi comments

* Cleaned up NormInstance comments

* Cleaned up NormNode comments

* Cleaned up NormObject comments

* Cleaned up NormSession comments

* Cleaned up NormStream comments

* Cleaned up NormObject comments

* Adding commits

* Update get commit

* clean up on data and event

* Norm Data change

* clean up normfile docs

* clean up normstream

* clean up api docs

* Fixed data

* space approved

* Cleaned up NormData comment

* documentation clean up

* Update the ReadMe

* Cleaned up comments

* Added comments to NormAckingStatus

* Added comments to NormEventType

* Added comments to NormFecType

* Added comments to NormNackingMode

* Added comments to NormObjectType

* Added comments to NormProbingMode

* Added comments to NormRepairBoundary

* Added comments to NormFlushMode

* Added comments to NormSyncPolicy

* Cleaned up comments.  Fixed default for StartSender

* Added comments to constants

* Moved constants to relevant classes

* Updated design

* Removed NormDataDetachData since it is not referenced

* Updated design

* Updated input and output stream design

* Updated packaging README

* Removed language version since redundant

* Cleaned up project file

* Updated to package from the dotnet directory (test project is set to not pack)

* Added version to project

---------

Co-authored-by: syermak <syerm001@odu.edu>
Co-authored-by: Sylvester Freeman III <Slyfreeman3@gmail.com>
Co-authored-by: Sergiy <47069243+SergiyYermak@users.noreply.github.com>
Co-authored-by: mullerj <mullerj@users.noreply.github.com>

* NormSession typos in comments (#12)

* Fixed default function comments in NormSession

* Fixed typos in NormSession

* Fixed default function comments

* Feature/9 net norm extension target architecture packages (#13)

* Added Win64 project and release configuration

* Added project reference to Win64 project

* Added Win32 project. Moved norm build actions to scripts

* Added linux .NET extension project

* Modified linux project to copy to output directory

* Fixed linux pack script

* Changed Linux project to copy always

* Changed Linux project package path

* Moved Windows libraries to runtimes path

* Renamed runtime specific projects

* Codespace Configurations (#15)

* Created devcontainer.json

* .NET norm extension GitHub actions (#16)

* Added .NET action

* Update dotnet-publish.yml to use source branch (#18)

* .NET norm package publish (#19)

* Added steps to copy package and check workspace

* Changed trigger for testing

* Removed if statement

* Updated dotnet-publish.yml to copy to  $GITHUB_OUTPUT

* Changed from variable to path

* Removed copy command

* Modified to check runner directory

* Added step to publish package

* Added package write permission

* Added job to publish win-x64

* Fixed package win-x64 step

* Added job to publish win-x86

* Added skip-duplicate to publish commands

* Added publish job

* Changed to . for linux find

* Added workflow trigger

* Added branches filter

* Publish test results (#21)

* Added step to publish test results

* Changed upload step to use wildcard

* Added quotes

* Changed directory to relative path

* Fixed upload step

* Added step to publish test results

* Added permissions

* Dev Container extensions (#23)

* Added extensions

* Cut down on extensions

* Added extension

* Removed pull requests extension

* Added workspace recommendation

* Added powershell feature

* Fixed powershell version

* Updated powershell version and added extension

* Updated to latest powershell

* Dev Container performance (#25)

* Fixed devcontainer format

* Added dotnet-linux-x64 devcontainer

* Changed devcontainer image to python

* Pinned OS version

* Updated devcontainer base image

* Reverted changes to devcontainer

* Moved linux devcontainer file

* Updated dotnet-publish to use subfolder

* Revert "Dev Container performance (#25)" (#27)

This reverts commit 2be146ceed.

* Update action versions for dotnet-publish.yml

* Update action versions for dotnet.yml

* Fixed ReceivesData test to use received events for actual data

* NormData Refactor (#30)

* Switched NormData Data property to a method

* Corrected NormData summary comment

* Updated NormData GetData to use Marshal.Copy

* Fixed warnings

* Updated NormData design

* NormDataEnqueue Refactor (#31)

* Switched NormDataEnqueue to use IntPtr

* Updated NormApi design

* Updated GetSession to use lock

* Updated GetSession to TryGetValue

* DataEnqueue Refactor (#33)

* Refactored DataEnqueue to use pointer arithmetic

* NormDataEnqueue Refactor (#34)

* Updated to use SafeBuffer

* Added ByteBuffer and DirectByteBuffer

* Added pointer overload to DataEnqueue

* Updated FileEnqueue() to use pointer arithmetic

* Updated NormStream to use pointer arithmetic

* Updated NormSendCommand to nint

* Updated NormNodeGetCommand to nint

* Updated NormNodeGetAddress to use nint for buffer

* Updated NormStreamRead to use nint for buffer

* Updated NormObjectGetInfo to use nint for buffer

* Updated NormFileGetName nameBuffer to nint

* Updated NormFile.Name to use PtrToStringAnsi

* Updated NormFile.Name to use stackalloc (#37)

* Updated NormNode.Address to use stackalloc and create IPAddress from bytes

* NormObject Refactor

* Updated NormObjectGetInfo to use byte array

* Updated design

* NormStream Refactor

* Updated NormStream Write to use fixed statement

* Updated NormStream Read to use fixed statement

* Updated design

* NormNode Refactor

* Updated NormNodeGetAddress to use byte* to avoid casting

* Updated NormNode GetCommand to use fixed statement

* Updated design

* NormFile Refactor

* Updated NormFileGetName to use sbyte* to avoid casting

* Updated design

* Added workflow_dispatch to workflows

---------

Co-authored-by: Sergiy <sergiy.yermak.ctr@us.navy.mil>
Co-authored-by: syermak <syerm001@odu.edu>
Co-authored-by: mullerj <mullerj@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfree3@users.noreply.github.com>
Co-authored-by: Sergiy <47069243+SergiyYermak@users.noreply.github.com>
Co-authored-by: Sylvester Freeman III <Slyfreeman3@gmail.com>
2025-03-26 01:07:19 -04:00
PM 0c2e151a77
use data race safe gmtime variant as in NormSession::OnReportTimeout (#91)
Co-authored-by: Pat Mills <patrick.m.mills2@boeing.com>
2025-03-26 01:03:34 -04:00
Brian Adamson 9a613d4150
Update cmake.yml 2025-03-26 01:01:30 -04:00
Brian Adamson a626a98f63
Update cmake.yml 2025-03-26 00:59:42 -04:00
Brian Adamson d4faaebba4
Update cmake.yml 2025-03-26 00:50:39 -04:00
Brian Adamson c8ffc272ee
Update cmake.yml 2025-03-26 00:48:43 -04:00
bebopagogo 006f9d29aa Merge branch 'master' of https://github.com/USNavalResearchLaboratory/norm 2025-01-26 20:27:11 -05:00
bebopagogo b7b252fd55 fixes to npc (NormPrecoder) and updated its documentation. Include 'auto' block sizing' feature 2025-01-26 20:26:49 -05:00
bebopagogo 7a6c09ae17 fixes to npc (NormPrecoder) and updated its documentation. Include 'auto' block sizing' feature 2025-01-26 20:13:35 -05:00
bebopagogo 9a28f755cf pulled updated submodule code 2025-01-02 11:27:11 -05:00
bebopagogo bc6e81feda fix to limit rate increase to no more than double during slow start 2025-01-02 11:19:11 -05:00
bebopagogo 0c6e516c90 pulled updated submodule code 2024-12-27 21:28:52 -05:00
bebopagogo 2dfd41a0c5 fix to waf build of normCast example 2024-12-27 16:32:05 -05:00
bebopagogo 669fc4f671 brought in protolib with bug fixes 2024-06-08 18:13:29 -04:00
bebopagogo ebc65bd140 pulled updated submodule code 2024-06-08 17:39:28 -04:00
bebopagogo 78052bdb29 Update incl. fix to MacOS Makefile
Merge branch 'master' of https://github.com/USNavalResearchLaboratory/norm
2024-06-08 17:38:36 -04:00
bebopagogo f242b53b72 fix to MacOS Makefile 2024-06-08 17:38:25 -04:00
bebopagogo 8da63844ed some 'norp' code cleanup 2024-06-08 17:22:13 -04:00
bebopagogo 0015af3bb6 some 'norp' code cleanup 2024-06-08 17:20:27 -04:00
bebopagogo 2ae69e6e96 fix to NormFile::Open() where 'flags' were not properly saved and affected NormFile::Rename() 2024-01-28 20:26:15 -05:00
bebopagogo 6188965887 fixed improper delete operator usage in normApp.cpp and minor tweaks 2024-01-24 13:43:38 -05:00
LVancina a992176873
Documentation updates and pynorm example bug fixes (#82)
* Added notes about waf execution in BUILD.TXT

* Updated instructions for cloning and running make

* Added more detailed instructions for win32 builds

* Fixed typo on line 20 (capitalized 'f') that caused the command to fail

* Generic editing and replaced dead URLs

* Substituted setuptools package for the deprecated distutils in setup.py

* Fixed typo in 'norm.exe' file path in Win32 build instructions

* Fixed a bugs in normCast.py and normFileSend.py

---------

Co-authored-by: Lucas <lucas.vancina@nps.edu>
2024-01-24 13:15:06 -05:00
bebopagogo af9a238a70 pulled updated submodule code 2023-09-03 15:01:44 -04:00
bebopagogo 4b34fffa8e pulled updated submodule code 2023-09-02 22:16:16 -04:00
bebopagogo 8ae9df5607 updated gradle and tweaked build.gradle file to API version 24 2023-09-02 22:15:23 -04:00
bebopagogo 69a9e4828d added examples/chant.cpp for simple command-line NORM chat app 2023-06-03 23:05:39 -04:00
bebopagogo 34e582bfac added examples/chant.cpp for simple command-line NORM chat app 2023-05-31 20:10:16 -04:00
bebopagogo a15e91379e added examples/chant.cpp for simple command-line NORM chat app 2023-05-31 19:56:18 -04:00
bebopagogo 11b271cc28 added examples/chant.cpp for simple command-line NORM chat app 2023-05-31 19:51:22 -04:00
bebopagogo 1af8531178 added examples/chant.cpp for simple command-line NORM chat app 2023-05-31 19:32:47 -04:00
bebopagogo 17dc41ab72 added examples/chant.cpp for simple command-line NORM chat app 2023-05-31 19:30:36 -04:00
bebopagogo 61b6e31f6f pulled updated submodule code 2023-01-29 20:02:52 -05:00
bebopagogo 5b7239523f pulled updated submodule code 2023-01-28 17:18:34 -05:00
bebopagogo 78d7ac78a2 pulled updated submodule code 2023-01-28 17:00:37 -05:00
bebopagogo a319a5b2d6 pulled updated submodule code 2023-01-28 16:10:56 -05:00
bebopagogo 6e7f2c3548 pulled updated submodule code 2023-01-28 16:09:22 -05:00
mullerj b8ce922a36
Fixed NormStreamSend (#1) (#77) 2023-01-16 16:44:29 -05:00
bebopagogo c0463960cb updated some sprintf() calls to snprint() 2023-01-14 17:30:04 -05:00
bebopagogo 92927c8a37 updated pynorm Python binding to use Python 3 contributions from Honglei 2022-11-11 20:17:30 -05:00
bebopagogo 6318f9bf62 pulled updated submodule code 2022-10-04 19:23:39 -04:00
bebopagogo 9f65f5e20a pynorm improvement to keep cache sender enqueued objects in pynorm.instance._objects cache 2022-10-04 19:21:41 -04:00
bebopagogo 40717bb5dd pulled updated submodule code 2022-09-11 21:58:42 -04:00
Brian Adamson b7f2a7073b
Update cmake.yml
Updated to 2022 MSVC CI
2022-09-11 21:41:50 -04:00
Brian Adamson 360996e4c7
Update cmake.yml 2022-09-11 21:37:13 -04:00
Brian Adamson dbbbee1798
Update cmake.yml 2022-09-11 21:25:03 -04:00
Brian Adamson ddd02a9010
Update cmake.yml 2022-09-11 21:19:33 -04:00
bebopagogo 4fe403e7d8 pulled updated submodule code 2022-09-11 20:58:47 -04:00
bebopagogo b43af9fc85 pulled updated submodule code 2022-09-11 18:14:26 -04:00
bebopagogo f1e240cb28 pulled updated submodule code 2022-09-11 17:23:31 -04:00
bebopagogo 80fa426b0b cleaned up Visual Studio build configurations 2022-09-11 17:21:06 -04:00
bebopagogo 8842897961 cleaned up Visual Studio build configurations 2022-09-11 17:20:15 -04:00
Brian Adamson 5adfa5902c
Update README.TXT 2022-09-11 14:34:50 -04:00
bebopagogo e9658ab837 fixed type casting issue with NormSenderNode::backoff_factor 2022-09-11 14:29:58 -04:00
bebopagogo d00ebc22d2 fixed type casting issue with NormSenderNode::backoff_factor 2022-09-11 14:27:21 -04:00
bebopagogo acbc31c1d0 added 'reuse' and 'txport' command-line options in addition to 'txaddr' option 2022-09-10 20:20:34 -04:00
Honglei ea8a22c180
Add txAddr/txPort to normCast.cpp (#73)
* Add txAddr/txPort to normCast.cpp

* add missing txAddr usage for normCast.cpp
2022-09-10 20:00:08 -04:00
bebopagogo b896f5408f update to NormSession::DeleteTxObject() to close file for NORM_OBJECT_FILE _befere_ issuing PURGE notification 2022-09-07 11:48:40 -04:00
bebopagogo 2e3d00e254 pulled updated submodule code with ProtoEvent::Close() WIN32 fix 2022-08-27 10:38:30 -07:00
bebopagogo 61a87e6b5f updated submodule 2022-08-21 00:57:47 -04:00
adamson a00ea1b2df pulled updated submodule code 2022-08-21 00:33:34 -04:00
adamson e8fe5f4fcd file renaming improvement 2022-08-21 00:31:00 -04:00
bebopagogo f8edc36cbf tweak 2022-08-21 00:24:44 -04:00
bebopagogo a8c5688d40 updated NormFile::Rename() to always close/reopen files upon renaming for better performance due to way file handles are managed on Unix ... was already required for Windows 2022-08-21 00:18:29 -04:00
bebopagogo 5872195eaa refinement/improvement to inactive sender timeout/reactivation 2022-08-20 22:52:05 -04:00
Brian Adamson d1d69f7820 formatting 2022-08-20 22:45:59 -04:00
Brian Adamson 684c7303e2 Merge branch 'master' of https://github.com/USNavalResearchLaboratory/norm 2022-08-20 22:36:52 -04:00
Brian Adamson 001d50aa46 pynorm fixes 2022-08-20 22:36:29 -04:00
Honglei a08f387ec5
Make Session.getReportInterval work (#68)
* Update core.py

libnorm.NormGetReportInterval.argtypes missed

* Update session.py

getReportInterval Need return the  value

* fix Unknown command FetchContent_MakeAvailable

-- Building protokit from c51d4a771b0ccb073a78e1cf60f0deb7d652f382
CMake Error at CMakeLists.txt:63 (FetchContent_MakeAvailable):
  Unknown CMake command "FetchContent_MakeAvailable".

https://github.com/EMsoft-org/EMsoft/issues/93
2022-07-18 16:54:09 -04:00
bebopagogo a1bb33c354 added full parameter set to pynorm.Session.setTxPort() 2022-07-02 17:07:23 -04:00
Jeffery Weston cc3a29b025 added processor commands for sent and purged files on sender side for additional inter-process flexibility 2022-05-25 16:44:44 -04:00
Jeffery Weston f7f9d794f9 change silent receiver syntax, allow enabling/disabling at runtime via protopipe in normCastApp 2022-05-24 14:54:51 -04:00
bebopagogo 858be37709 fixes to pynorm for Python3 and normMsgr.py and normFileSend.py examples 2022-05-22 23:17:58 -04:00
bebopagogo 1ba16231bb fix to pynorm Session.setRxPortReuse() method 2022-05-22 22:08:57 -04:00
bebopagogo 5cd6498c39 fixes to pynorm for Python3 and normMsgr.py and normFileSend.py examples 2022-05-22 22:01:47 -04:00
bebopagogo 972b1a3e0b fixes to pynorm for Python3 and normMsgr.py and normFileSend.py examples 2022-05-22 21:52:45 -04:00
Jeffery Weston 9e796e69b2 add protoApp version of normCast (normCastApp) -- includes realtime protopipe for runtime control using a subset of commands (rate, CC, autoparity, loss) 2022-05-19 16:55:37 -04:00
Jeffery Weston 22aceaa271 code cleanup 2022-05-19 16:25:48 -04:00
bebopagogo 76023bd750 protolib rollup 2022-05-09 11:36:06 -04:00
bebopagogo 053aa16eb8 normCast improvements 2022-05-09 11:35:32 -04:00
bebopagogo e9e3c99b21 update to NORM_SYNC_ALL policy 2022-05-09 11:33:01 -04:00
bebopagogo 46a030891d NORM_SYNC_ALL policy improvement 2022-05-09 11:30:24 -04:00
bebopagogo c29ef4adbd cleanup 2022-05-09 11:29:07 -04:00
bebopagogo 039e70d601 cleanup 2022-05-09 11:28:17 -04:00
bebopagogo b9fab02215 cleanup 2022-05-09 11:26:53 -04:00
bebopagogo ebd51d79de clean up 2022-05-09 11:25:15 -04:00
bebopagogo 6f59618f4a updated android build files to more recent gradle wrapper and Android SDK versions to work with Android Studio Bumblebee release 2022-05-08 16:52:10 -04:00
bebopagogo 3fd9bad54e fix so that when NormSyncPolicy is NORM_SYNC_ALL, receivers will NACK in reponse to NORM_CMD(FLUSH) messages received. Also updated normCast example behavior making 'ack auto' operation more robust. 2022-05-08 16:49:04 -04:00
Jeffery Weston 2558ffcdc7 add option to set GRTT probing mode 2022-05-05 16:34:58 -04:00
Jeffery Weston 38b61e3320 Added ability to exit sender on successful FLUSH process in non-ACK & non-repeat modes. Added supporting 'grtt' commandline option to set initial GRTT estimate which affects the amount of time the FLUSH process takes. 2022-05-05 10:10:05 -04:00
Jeffery Weston 8c9f0951ff add rxloss to examples 2022-05-03 14:21:11 -04:00
Jeffery Weston b997771fec Update unix postprocessor code to allow for a fixed number of simultaneous postprocessor child processes. Previous behavior killed the previous process in order to start a new one. Also correctly tracks when they die. 2022-04-29 13:47:07 -04:00
Philip Cali 5dc78909ce
feat: adding dockerfile for docker image building (#56)
* feat: adding docker support

* fix: typo in README
2022-04-28 22:06:43 -07:00
Jeffery Weston 7c5afec284 correct usage 2022-04-28 10:45:06 -04:00
Jeffery Weston d1e8413cd3 added 'processor' and 'saveaborts' options to normCast 2022-04-27 11:24:47 -04:00
Brian Adamson be88d6e79a
Delete local.properties
Android "local.properties" files should not be checked into version control.  They contain information that is only relevant to the local development environment (e.g. paths to android tools, etc)
2021-12-03 18:05:15 -05:00
Alessandro Grossmann 29bd835c69
Reconfigured the android Gradle build (#47)
* CMakeLists.txt now build jar with ant and gradle package .jar into .aar. Updated README with instructions.

* Updated instructions.

* Fixed code block formatting.

* Replcaing txt with md.

* Fixed formatting.

* Removed README.TXT.
2021-12-03 18:01:38 -05:00
bebopagogo 4f6f663671 fix to normCast repeat feature 2021-09-28 19:53:57 -04:00
bebopagogo 12c729aaff added Android gradle CMakelists file, etc 2021-09-17 20:16:41 -04:00
bebopagogo 5bf8b44cff updated normCast usage help 2021-09-12 22:38:40 -04:00
bebopagogo 3306537ded updated normCast usage help 2021-09-12 22:35:28 -04:00
bebopagogo b44ce93125 update to normCast example, adding 'hot outbox' capability 2021-09-12 10:39:06 -04:00
bebopagogo 1bca647ef4 update protolib submodule 2021-06-03 00:58:09 -04:00
Jeffery Weston 4746eafe4f add norp executable to .gitignore 2021-04-30 09:59:30 -04:00
protohuf ddb974e0ae
Changed variable name of NormNodeHandle in NormEvent to match what is (#30)
defined in normApi.h
2021-04-07 14:25:08 -04:00
Jeff Weston 476b8bb7eb
fix API compilation error (#27) 2021-04-07 14:20:22 -04:00
bebopagogo 01e161a31a updated VERSION.TXT 2021-03-14 23:06:07 -04:00
bebopagogo b66598c119 fixes to experimental NormSocket API 2021-03-14 21:23:29 -04:00
Luca Boccassi 9c367b50bc
pkg-config, PIE, API breakages fixes (#23)
* Update protolib to pick up new fixes

* CMake: restore SONAME_VERSION to 1

* CMake: generate pkg-config file

* CMake: set -fvisibility=hidden and POSITION_INDEPENDENT_CODE

Need to build everything with fPIC, and also hide symbols by default,
since public ones are explicitly marked as such.

* Revert public API incompatible changes

NormSetId and NormCountCompletedObjects were part of the public API in
released versions, so they cannot be just removed without breaking API/ABI
compatibility.
NormSendCommandTo is a private symbol, but was marked for export by
mistake.

* Add BUILD_STATIC_LIBS option to allow building both static and shared objects

CMake does not support this out of the box, so it has to be implemented
manually. It results in the libnorm build being repeated twice, as there's
no object sharing.
2021-02-01 10:20:20 -05:00
bebopagogo 213adb3938 updated wf wscript to check for existence of ctx.options.enable_static_library attribute before trying access it 2021-02-01 09:52:50 -05:00
rui 789ca317d6
fix README layout (#21) 2021-02-01 09:32:17 -05:00
rui d73491bc28
update waf build reference (#22) 2021-02-01 09:31:31 -05:00
bebopagogo 54bb708d48 rolled up development version to 1.5.10 2021-01-30 18:32:28 -05:00
341 changed files with 20466 additions and 1594 deletions

View File

@ -0,0 +1,39 @@
{
"image": "mcr.microsoft.com/devcontainers/cpp:1.0.0-buster",
"features": {
"ghcr.io/devcontainers/features/python:1": {
"version": "3.11"
},
"ghcr.io/devcontainers/features/dotnet:1": {
"version": "6"
},
"ghcr.io/devcontainers/features/java:1": {
"version": "17",
"installAnt": true,
"antVersion": "1.10.12"
},
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "20.10"
},
"ghcr.io/devcontainers/features/powershell:1": {
"version": "7.3"
}
},
"customizations": {
"vscode": {
"extensions": [
"DavidAnson.vscode-markdownlint",
"eamodio.gitlens",
"github.vscode-github-actions",
"GitHub.codespaces",
"jebbs.plantuml",
"ms-python.isort",
"ms-vscode-remote.remote-containers",
"ms-vscode.cpptools-themes",
"ms-vscode.PowerShell",
"tomoki1207.pdf",
"yzhang.markdown-all-in-one"
]
}
}
}

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.sh text eol=lf

17
.github/workflows/cmake.yml vendored Normal file → Executable file
View File

@ -17,18 +17,19 @@ jobs:
matrix:
config:
- {
name: "Windows Latest MSVC Shared", artifact: "Windows-MSVC-shared.tar.xz",
os: windows-latest,
name: "Windows 2022 MSVC Shared", artifact: "Windows-MSVC-shared.tar.xz",
os: windows-2022,
cc: "cl", cxx: "cl",
shared: "ON",
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
environment_script: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
}
- {
name: "Windows Latest MSVC", artifact: "Windows-MSVC.tar.xz",
os: windows-latest,
name: "Windows 2022 MSVC", artifact: "Windows-MSVC.tar.xz",
os: windows-2022,
cc: "cl", cxx: "cl",
shared: "OFF",
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
environment_script: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
}
- {
name: "Windows Latest MinGW", artifact: "Windows-MinGW.tar.xz",
@ -50,7 +51,7 @@ jobs:
}
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4
- name: Download Ninja and CMake
id: cmake_and_ninja
@ -101,7 +102,7 @@ jobs:
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
message("::set-output name=timestamp::${current_date}")
- name: ccache cache files
uses: actions/cache@v1.1.0
uses: actions/cache@v4
with:
path: .ccache
key: ${{ matrix.config.name }}-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }}

142
.github/workflows/dotnet-publish.yml vendored Normal file
View File

@ -0,0 +1,142 @@
name: ".NET Publish"
on:
workflow_run:
workflows: ['.NET']
types:
- completed
branches:
- master
- main
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
permissions:
packages: write
defaults:
run:
working-directory: ./src/dotnet
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
env:
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Package .NET
run: dotnet pack . -c Release
- name: Publish .NET
run: |
package=$(find . -type f -name "*.nupkg")
dotnet nuget push "$package" --skip-duplicate
publish-linux-x64:
runs-on: ubuntu-latest
permissions:
packages: write
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Package .NET
uses: devcontainers/ci@v0.3
with:
push: never
runCmd: |
cd ./src/dotnet
chmod 755 *.sh
./pack-linux-x64.sh
- name: Set up .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
env:
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Publish .NET
run: |
package=$(find . -type f -name "*linux-x64*.nupkg")
dotnet nuget push "$package" --skip-duplicate
publish-win-x64:
runs-on: windows-latest
permissions:
packages: write
defaults:
run:
working-directory: ./src/dotnet
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Python
uses: actions/setup-python@v5.1.0
with:
python-version: 3.x
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
env:
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Package .NET
run: .\pack-win-x64.bat
- name: Publish .NET
run: |
$package=Get-ChildItem -Path .\ -Filter *win-x64*.nupkg -Recurse -File | ForEach-Object { $_.FullName }
dotnet nuget push "$package" --skip-duplicate
publish-win-x86:
runs-on: windows-latest
permissions:
packages: write
defaults:
run:
working-directory: ./src/dotnet
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Python
uses: actions/setup-python@v5.1.0
with:
python-version: 3.x
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
env:
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Package .NET
run: .\pack-win-x86.bat
- name: Publish .NET
run: |
$package=Get-ChildItem -Path .\ -Filter *win-x86*.nupkg -Recurse -File | ForEach-Object { $_.FullName }
dotnet nuget push "$package" --skip-duplicate

49
.github/workflows/dotnet.yml vendored Normal file
View File

@ -0,0 +1,49 @@
name: .NET
on: [push, pull_request, workflow_dispatch]
jobs:
build:
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
defaults:
run:
working-directory: ./src/dotnet
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Python
uses: actions/setup-python@v5.1.0
with:
python-version: 3.x
- name: Build NORM
run: ./waf
working-directory: .
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore /property:Configuration=Release
- name: Build
run: dotnet build --no-restore --configuration Release
- name: Test
run: dotnet test --no-build --verbosity normal --configuration Release --logger trx --results-directory TestResults
- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: dotnet-results
path: ./src/dotnet/TestResults
if: ${{ always() }}
- name: Publish test results
uses: EnricoMi/publish-unit-test-result-action@v2
with:
files: ./src/dotnet/TestResults/*.trx
if: ${{ always() }}

286
.gitignore vendored Normal file → Executable file
View File

@ -1,25 +1,37 @@
# build executables
build/
lib/
bin/
makefiles/norm
makefiles/normMsgr
makefiles/normStreamer
makefiles/normCast
makefiles/normCastApp
makefiles/normClient
makefiles/normServer
makefiles/npc
makefiles/raft
makefiles/pcap2norm
norp/makefiles/norp
# build object files
*.o
*.a
# python build files
src/pynorm.egg-info
**/__pycache__/
# build java files
*.class
#build android files
android/.gradle
# waf cruft
.waf*
.lock-waf*
waf*/*
# OS generated files #
.DS_Store
@ -29,3 +41,275 @@ makefiles/pcap2norm
.Trashes
ehthumbs.db
Thumbs.db
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
*.sqlite
*.sqlite-shm
*.sqlite-wal
# Nuget files
DeploymentSettings.props
Directory.Build.props
Directory.Build.targets
Packages.props
#Local Log Files
log*.txt
#.NET Extension Library Files
/src/dotnet/lib

0
.gitmodules vendored Normal file → Executable file
View File

5
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"recommendations": [
"github.vscode-pull-request-github"
]
}

25
BUILD.TXT Normal file → Executable file
View File

@ -6,11 +6,26 @@ To see a full list of options, run:
./waf -h
Note: if attempting to run waf as an executable as shown above results in a
message like this:
/usr/bin/env: python: No such file or directory
then try calling python directly:
python waf <args>
or
python3 waf <args>
For more background information about waf, visit the gitlab page at
https://gitlab.com/ita1024/./waf/
Configuring
-----------
To perform the configure checks, run:
To perform the configuration checks, run:
./waf configure
@ -51,6 +66,9 @@ To install, run:
This will install the compiled library and headers to wherever your prefix was
specified. (See configure flags)
This command may have to be run with root priviledges for certain prefix
directories depending on your system setup.
Uninstalling
------------
@ -70,3 +88,8 @@ will delete all compiled files and configuration settings.
./waf distclean
will do the same as clean, and additionally delete the waf cache files.
ANDROID Build
-------------
See the "android" directory README for instructions.

39
CMakeLists.txt Normal file → Executable file
View File

@ -1,7 +1,11 @@
cmake_minimum_required(VERSION 3.11)
cmake_minimum_required(VERSION 3.14)
cmake_policy(SET CMP0077 NEW)
# set the project name
project(norm VERSION 1.5.8)
project(norm VERSION 1.5.10)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(COMMON src/common)
@ -121,12 +125,26 @@ target_compile_options(norm PUBLIC ${PLATFORM_FLAGS})
target_include_directories(norm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(norm PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>)
if(BUILD_SHARED_LIBS AND WIN32)
target_compile_definitions(norm PUBLIC NORM_USE_DLL)
if(BUILD_SHARED_LIBS)
set_target_properties(norm PROPERTIES SOVERSION 1.5.10)
if(WIN32)
target_compile_definitions(norm PUBLIC NORM_USE_DLL)
endif()
endif()
if(BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS)
add_library(norm-static STATIC ${PLATFORM_SOURCE_FILES} ${COMMON_SOURCE_FILES} ${PUBLIC_HEADER_FILES})
target_link_libraries(norm-static PRIVATE protokit::protokit)
target_compile_definitions(norm-static PUBLIC ${PLATFORM_DEFINITIONS})
target_compile_options(norm-static PUBLIC ${PLATFORM_FLAGS})
target_include_directories(norm-static PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(norm-static PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>)
set_target_properties(norm-static PROPERTIES OUTPUT_NAME "norm" PREFIX "lib")
set(NORM_STATIC "norm-static")
endif()
# Install target
install( TARGETS norm protokit EXPORT normTargets
install( TARGETS norm ${NORM_STATIC} protokit EXPORT normTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
@ -142,6 +160,16 @@ install( EXPORT normTargets
install(FILES include/normApi.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# Create pkg-config file norm.pc
# TODO: once waf is removed, norm.pc.in can be edited to use the variables CMake sets directly, and
# remove these re-definitions
set(VERSION ${PROJECT_VERSION})
set(PREFIX ${CMAKE_INSTALL_PREFIX})
set(LIBDIR ${CMAKE_INSTALL_LIBDIR})
set(STATIC_LIBS "libprotokit.a")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/norm.pc.in ${CMAKE_CURRENT_BINARY_DIR}/norm.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/norm.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# Create a ConfigVersion.cmake file
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
@ -184,6 +212,7 @@ if(NORM_BUILD_EXAMPLES)
normMsgr
normStreamer
normCast
chant
normClient
normServer
#wintest

27
Dockerfile Executable file
View File

@ -0,0 +1,27 @@
ARG platformName=ubuntu
ARG platformVersion=latest
FROM ${platformName}:${platformVersion}
ARG version
ARG configure
ARG build="--targets=*"
ENV NORM_DIR=/norm-staging
ENV NORM_BUILD=$NORM_DIR/build
ENV WAF_CONFIGURE=${configure}
ENV WAF_BUILD=${build}
ADD ./ ${NORM_DIR}
# Step 1: dependencies
RUN VERSION=${version} ${NORM_DIR}/docker/setup.sh
# Step 2: build
RUN cd ${NORM_DIR} && ./waf ${WAF_BUILD}
# Step 3: install
RUN cd ${NORM_DIR} && ./waf install
# Step 4: expose
COPY ./docker/run.sh /usr/bin/run-norm-example
ENTRYPOINT [ "run-norm-example" ]

0
LICENSE Normal file → Executable file
View File

0
NormSocketBindingNotes.txt Normal file → Executable file
View File

72
README-DotNet.md Normal file
View File

@ -0,0 +1,72 @@
.NET extension for NORM
==========================
By:
Jeff Muller <jeffrey.muller3.ctr@us.navy.mil>
Sylvester Freeman <sylvester.freeman18.civ@us.navy.mil>
Sergiy Yermak <sergiy.yermak.ctr@us.navy.mil>
The .NET extension for NORM provides a .NET wrapper for the NORM C API.
For documentation about the main NORM API calls, refer to the NORM Developers
guide in the regular NORM distribution.
The .NET extension can be built using the .NET CLI.
------------
Requirements
------------
The .NET extension for NORM requires at least .NET SDK 6.0.
The NORM library should be built prior to building the .NET extension since it is invoked by the .NET extension.
------------
Building
------------
To build the .NET extension for NORM, execute the .NET CLI command in the src/dotnet directory:
```
dotnet build .
```
------------
Testing
------------
To test the .NET extension for NORM, execute the .NET CLI command in the src/dotnet directory:
```
dotnet test .
```
The test command results should show that all tests have passed.
Some tests might be skipped due to IO exception.
------------
Packaging
------------
To package the .NET extension for NORM, execute the .NET CLI command in the src/dotnet directory:
```
dotnet pack . -c Release
```
To package the .NET extension for NORM that targets 64-bit Windows, execute the command in the src/dotnet directory:
```
pack-win-x64.bat
```
To package the .NET extension for NORM that targets 32-bit Windows, execute the command in the src/dotnet directory:
```
pack-win-x86.bat
```
To package the .NET extension for NORM that targets 64-bit Linux, execute the command in the src/dotnet directory:
```
./pack-linux-x64.sh
```

0
README-Java.txt Normal file → Executable file
View File

2
README-PyNorm.txt Normal file → Executable file
View File

@ -28,7 +28,7 @@ in similar places as your system's compiler. On UNIX systems, this is usually
PATH environment variable.
On Windows, PyNORM requires the "PyWin32" module, available at:
http://sf.net/projects/pywin32
https://sourceforge.net/projects/pywin32
-------------
Installation

39
README.md Normal file → Executable file
View File

@ -1,4 +1,6 @@
# norm
```
NORM SOURCE CODE RELEASE
/*********************************************************************
@ -29,6 +31,7 @@
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
********************************************************************/
```
This is the NRL NORM source code repository.
@ -96,6 +99,37 @@ More info is available in the norp/doc directory, as well as the
NORP website: https://www.nrl.navy.mil/itd/ncs/products/norp
Docker
======
A `Dockerfile` is provided to facilitate containerized NORM environment testing. Notable
build arguments passed to `docker build` will influence how the image is created.
- `platformName` represents the base image name (defaults to `ubuntu`)
- `platformVersion` represents the tagged version for the base image (defaults to `latest`)
- `version` is a 1:1 mapping to this repo's tag (defaults to `v1.5.9`)
- `configure` is piped to `./waf configure` (defaults to "")
- `build` is piped to `./waf` (defaults to `--targets=*`)
Example usage:
CentOS7 build
```
docker build --build-arg platformName=centos \
--build-arg platformVersion=7 \
--build-arg="--build-java" \
-t norm:centos-1.5.9 .
```
Running the data send and recv examples:
```
# Sender in one terminal
docker run -it --rm --name norm-send <norm:image> normDataSend
# Receiver in another terminal
docker run -it --rm --name norm-recv <norm:image> normDataRecv
```
OTHER FILES:
============
@ -112,6 +146,8 @@ VERSION.TXT - NORM version history notes
README.md - this file
docker - directory containing docker container support
NOTES:
======
@ -138,6 +174,3 @@ git checkout master
This will enable you to issue 'git pull', etc to treat the 'protolib'
sub-directory as its own (sub-) repository.

0
TODO.TXT Normal file → Executable file
View File

6
VERSION.TXT Normal file → Executable file
View File

@ -1,7 +1,11 @@
NORM Version History
Version 1.5.9 (in progress)
Version 1.5.10 (in progress)
=============
- NormSocket API improvements
Version 1.5.9
=============
- Added "normCast" file send/receive example
- Protolib ProtoTimer fix for "long" timeout intervals

View File

@ -1,20 +0,0 @@
This directoy contains Android Studio project files for building the NORM
library for Android.
TO BUILD:
./gradlew build
The lib/build/ directory will contain the binary libraries built.
The "./gradlew clean" command can be used to delete the files built.
This directory may also be opened as an Android Studio project and built from
the IDE GUI.
This will evolve as we update NORM and associated projects to the newer Android
Studio tool chain.

61
android/README.md Executable file
View File

@ -0,0 +1,61 @@
This directory contains Android Studio project files for building the NORM
library for Android.
REQUIREMENTS:
Ninja is required in order to run the ant build for the java .jar file
Download and install ndk and cmake using the SDK manager within Android Studio. To do this:
-> Tools -> SDK Manager -> System Settings -> Android SDK -> SDK Tools -> Select 'Show Package Details' at the bottom
The latest compatible versions are ndk version 20.0.5594570 and cmake version 3.10.2.4988404
* Important *
If you decide to install different version of the SDK Tools above, make sure to edit the path locations in the local.properties file
TO BUILD:
./gradlew build
The lib/build/ directory will contain the binary libraries built.
The "./gradlew clean" command can be used to delete the files built.
This directory may also be opened as an Android Studio project and built from
the IDE GUI.
This will evolve as we update NORM and associated projects to the newer Android
Studio tool chain.
USAGE:
Copy the .aar file into your ${project.rootDir}/app/libs/ folder
Within your app level build.gradle include the following two tasks before your dependencies section:
```
task extractSo(type: Copy) {
println 'Extracting *.so file(s)....'
from zipTree("${project.rootDir}/app/libs/lib-release_-release.aar")
into "${project.rootDir}/app/src/main/jniLibs"
include "jni/**/*.so"
eachFile {
def segments = it.getRelativePath().getSegments() as List
println segments
it.setPath(segments.tail().join("/"))
return it
}
includeEmptyDirs = false
}
task extractJar(type: Copy, dependsOn: extractSo) {
println 'Extracting *.jar file(s)....'
from zipTree("${project.rootDir}/app/libs/lib-release_-release.aar")
into "${project.rootDir}/app/libs/"
include "norm-*.jar"
}
```

2
android/build.gradle Normal file → Executable file
View File

@ -4,7 +4,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.1'
classpath 'com.android.tools.build:gradle:4.2.1'
}
}

0
android/gradle/wrapper/LICENSE-for-gradlewrapper.txt vendored Normal file → Executable file
View File

BIN
android/gradle/wrapper/gradle-wrapper.jar vendored Normal file → Executable file

Binary file not shown.

6
android/gradle/wrapper/gradle-wrapper.properties vendored Normal file → Executable file
View File

@ -1 +1,5 @@
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

298
android/gradlew vendored
View File

@ -1,74 +1,129 @@
#!/usr/bin/env bash
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn ( ) {
warn () {
echo "$*"
}
} >&2
die ( ) {
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@ -77,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@ -85,76 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

53
android/gradlew.bat vendored Normal file → Executable file
View File

@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@ -8,20 +24,23 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -45,34 +64,14 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell

80
android/lib/CMakeLists.txt Executable file
View File

@ -0,0 +1,80 @@
cmake_minimum_required(VERSION 3.4.1)
project("norm")
add_definitions("-DANDROID=1" "-DANDROID_API_VERSION=24" "-DPUSH_NOTIFICATIONS=1" "-DANDROID" "-DLINUX" "-DUNIX" "-DHAVE_IPV6" "-DHAVE_DIRFD" "-DPROTO_DEBUG" "-DHAVE_ASSERT" "-DHAVE_GETLOGIN" "-DUSE_SELECT" "-D_FILE_OFFSET_BITS=64" "-DHAVE_OLD_SIGNALHANDLER" "-DHAVE_SCHED" "-DNO_SCM_RIGHTS" "-Wno-attributes" "-DAPP_VERSION=1.0.0" "-DAPP_VERSION_HEX=0x10000")
include_directories( AFTER
"../../OID_NDK}/sources/android/cpufeatures"
"../../include"
"../../protolib/include"
)
find_program(ANTPATH ant)
execute_process(
COMMAND ${ANTPATH}
WORKING_DIRECTORY "$ENV{HOME}/norm/makefiles/java/"
)
enable_language(ASM)
IF(BUILD_CONFIGURATION MATCHES "DEBUG")
SET(BINARY_NAME "norm")
add_definitions("-DDEBUG=1" "-D_DEBUG=1")
ELSEIF(BUILD_CONFIGURATION MATCHES "RELEASE")
SET(BINARY_NAME "norm")
add_definitions("-DNDEBUG=1")
ELSE(BUILD_CONFIGURATION MATCHES "DEBUG")
MESSAGE( FATAL_ERROR "No matching build-configuration found." )
ENDIF(BUILD_CONFIGURATION MATCHES "DEBUG")
add_subdirectory("../../protolib/android/lib" ./protolib)
add_library( ${BINARY_NAME}
STATIC
"../../src/common/galois.cpp"
"../../src/common/normApi.cpp"
"../../src/common/normEncoder.cpp"
"../../src/common/normEncoderMDP.cpp"
"../../src/common/normEncoderRS16.cpp"
"../../src/common/normEncoderRS8.cpp"
"../../src/common/normFile.cpp"
"../../src/common/normMessage.cpp"
"../../src/common/normNode.cpp"
"../../src/common/normObject.cpp"
"../../src/common/normSegment.cpp"
"../../src/common/normSession.cpp"
)
add_library( mil_navy_nrl_norm
SHARED
"../../src/java/jni/normDataJni.cpp"
"../../src/java/jni/normEventJni.cpp"
"../../src/java/jni/normFileJni.cpp"
"../../src/java/jni/normInstanceJni.cpp"
"../../src/java/jni/normJni.cpp"
"../../src/java/jni/normNodeJni.cpp"
"../../src/java/jni/normObjectJni.cpp"
"../../src/java/jni/normSessionJni.cpp"
"../../src/java/jni/normStreamJni.cpp"
)
find_library(log "log")
find_library(android "android")
find_library(glesv2 "GLESv2")
find_library(egl "EGL")
target_link_libraries(mil_navy_nrl_norm
norm
protokit
${log}
${android}
${glesv2}
${egl}
)

142
android/lib/build.gradle Executable file
View File

@ -0,0 +1,142 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 34
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
signingConfigs {
normSigning {
storeFile file("${System.properties['user.home']}${File.separator}.android${File.separator}debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
storeType "jks"
}
}
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_PLATFORM=android-24", "-DCMAKE_MAKE_PROGRAM=/usr/local/bin/ninja", "-DANDROID_STL=c++_static", "-DANDROID_CPP_FEATURES=exceptions rtti", "-DANDROID_ARM_MODE=arm", "-DANDROID_ARM_NEON=TRUE"
cFlags "-fsigned-char"
cppFlags "-fsigned-char", "-std=c++14"
}
}
}
buildTypes {
debug {
initWith debug
debuggable true
jniDebuggable true
signingConfig signingConfigs.normSigning
}
release {
initWith release
debuggable false
jniDebuggable false
signingConfig signingConfigs.normSigning
}
}
flavorDimensions "default"
productFlavors {
debug_ {
ndk {
abiFilters "armeabi-v7a", "x86"
}
externalNativeBuild {
cmake {
targets "norm", "mil_navy_nrl_norm"
arguments "-DBUILD_CONFIGURATION=DEBUG", "-DCMAKE_CXX_FLAGS_DEBUG=-O0", "-DCMAKE_C_FLAGS_DEBUG=-O0"
}
}
dimension "default"
}
release_ {
externalNativeBuild {
cmake {
targets "norm", "mil_navy_nrl_norm"
arguments "-DBUILD_CONFIGURATION=RELEASE", "-DCMAKE_CXX_FLAGS_RELEASE=-O3", "-DCMAKE_C_FLAGS_RELEASE=-O3"
}
}
dimension "default"
}
}
variantFilter { variant ->
def names = variant.flavors*.name
if (names.contains ("debug_")
&& variant.buildType.name != "debug") {
setIgnore(true)
}
if (names.contains ("release_")
&& variant.buildType.name != "release") {
setIgnore(true)
}
}
repositories {
}
dependencies {
}
}
task copyReleaseJar(type: Copy) {
println 'Unzipping release .aar and including .jar....'
if (file("${project.rootDir}/lib/build/outputs/aar/lib-release_-release.aar").exists()) {
from zipTree("${project.rootDir}/lib/build/outputs/aar/lib-release_-release.aar")
into "${project.rootDir}/lib/build/outputs/aar/lib-release_-release"
from "${System.env.HOME}/norm/lib/norm-1.0.0.jar"
into "${project.rootDir}/lib/build/outputs/aar/lib-release_-release/"
}
}
task copyDebugJar(type: Copy, dependsOn: copyReleaseJar) {
println 'Unzipping debug .aar and including .jar....'
if (file("${project.rootDir}/lib/build/outputs/aar/lib-debug_-debug.aar").exists()){
from zipTree("${project.rootDir}/lib/build/outputs/aar/lib-debug_-debug.aar")
into "${project.rootDir}/lib/build/outputs/aar/lib-debug_-debug"
from "${System.env.HOME}/norm/lib/norm-1.0.0.jar"
into "${project.rootDir}/lib/build/outputs/aar/lib-debug_-debug/"
}
}
task zipReleaseAAR(type: Exec, dependsOn: copyDebugJar) {
println 'Creating new release .aar..'
ignoreExitValue true
workingDir "${project.rootDir}/lib/build/outputs/aar/"
executable 'jar'
def releaseArgsList = ['cvf', 'lib-release_-release.aar', '-C', 'lib-release_-release/', '.']
args releaseArgsList
}
task zipDebugAAR(type: Exec, dependsOn: zipReleaseAAR) {
println 'Creating new debug .aar..'
ignoreExitValue true
workingDir "${project.rootDir}/lib/build/outputs/aar/"
executable 'jar'
def debugArgsList = ['cvf', 'lib-debug_-debug.aar', '-C', 'lib-debug_-debug/', '.']
args debugArgsList
}
task deleteAARAssets(type: Delete, dependsOn: zipDebugAAR) {
delete "${project.rootDir}/lib/build/outputs/aar/lib-release_-release"
delete "${project.rootDir}/lib/build/outputs/aar/lib-debug_-debug"
}
this.build.finalizedBy(deleteAARAssets)

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0.0"
package="mil.navy.nrl.norm">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

0
android/settings.gradle Normal file → Executable file
View File

0
cmake/normConfig.cmake.in Normal file → Executable file
View File

0
doc/NormDeveloperGuide.html Normal file → Executable file
View File

0
doc/NormDeveloperGuide.pdf Normal file → Executable file
View File

43
doc/NormDeveloperGuide.xml Normal file → Executable file
View File

@ -13,19 +13,19 @@
<abstract>
<para>This document describes an application programming interface (API)
for the <ulink url="http://norm.pf.itd.nrl.navy.mil/">Nack-Oriented
for the <ulink url="https://www.nrl.navy.mil/Our-Work/Areas-of-Research/Information-Technology/NCS/NORM/">Nack-Oriented
Reliable Multicast (NORM)</ulink> protocol implementation developed by
the Protocol Engineering and Advance Networking (<ulink
url="http://cs.itd.nrl.navy.mil/">PROTEAN</ulink>) Research Group of the
United States <ulink url="http://www.nrl.navy.mil/">Naval Research
url="https://www.nrl.navy.mil/itd/ncs/">PROTEAN</ulink>) Research Group of the
United States <ulink url="https://www.nrl.navy.mil/">Naval Research
Laboratory</ulink> (NRL). The NORM protocol provides general purpose
reliable data transport for applications wishing to use Internet
Protocol (IP) Multicast services for group data delivery. NORM can also
support unicast (point-to-point) data communication and may be used for
such when deemed appropriate. The current NORM protocol specification is
given in the <ulink url="http://www.ietf.org/">Internet Engineering Task
given in the <ulink url="https://www.ietf.org/">Internet Engineering Task
Force</ulink> (IETF) <ulink
url="http://norm.pf.itd.nrl.navy.mil/rfc3940.pdf">RFC 3940</ulink>. This
url="https://datatracker.ietf.org/doc/html/rfc5740">RFC 5740</ulink>. This
document is currently a reference guide to the NORM API of the NRL
reference implementation. More tutorial material may be include in a
future version of this document or a separate developer's tutorial may
@ -37,19 +37,19 @@
<title>Background</title>
<para>This document describes an application programming interface (API)
for the <ulink url="http://norm.pf.itd.nrl.navy.mil/">Nack-Oriented
for the <ulink url="https://www.nrl.navy.mil/Our-Work/Areas-of-Research/Information-Technology/NCS/NORM/">Nack-Oriented
Reliable Multicast (NORM)</ulink> protocol implementation developed by the
Protocol Engineering and Advance Networking (<ulink
url="http://cs.itd.nrl.navy.mil/">PROTEAN</ulink>) Research Group of the
United States <ulink url="http://www.nrl.navy.mil/">Naval Research
url="https://www.nrl.navy.mil/itd/ncs/">PROTEAN</ulink>) Research Group of the
United States <ulink url="https://www.nrl.navy.mil/">Naval Research
Laboratory</ulink> (NRL). The NORM protocol provides general purpose
reliable data transport for applications wishing to use Internet Protocol
(IP) Multicast services for group data delivery. NORM can also support
unicast (point-to-point) data communication and may be used for such when
deemed appropriate. The current NORM protocol specification is given in
the <ulink url="http://www.ietf.org/">Internet Engineering Task
the <ulink url="https://www.ietf.org/">Internet Engineering Task
Force</ulink> (IETF) <ulink
url="http://norm.pf.itd.nrl.navy.mil/rfc5740.pdf">RFC 5740</ulink>.</para>
url="https://datatracker.ietf.org/doc/html/rfc5740">RFC 5740</ulink>.</para>
<para>The NORM protocol is designed to provide end-to-end reliable
transport of bulk data objects or streams over generic IP multicast
@ -134,7 +134,7 @@
may participate as senders and/or receivers within a NORM session. NORM
senders transmit data to the session destination address (usually an IP
multicast group) while receivers are notified of incoming data. The NORM
API provides and event notification scheme to notify the application of
API provides an event notification scheme to notify the application of
significant sender and receiver events. There are also a number support
functions provided for the application to control and monitor its
participation within a NORM transport session.</para>
@ -159,7 +159,7 @@
linkend="NormCreateInstance"><literal>NormCreateInstance()</literal></link>)
as needed for applications with specific requirements for accessing and
controlling participation in multiple <emphasis>NormSessions</emphasis>
from separate operating system multiple threads. Or, alternatively, a
from separate operating system threads. Or, alternatively, a
single <emphasis>NormInstance</emphasis> could be used, with a "master
thread" serving as an intermediary between the <link
linkend="NormGetNextEvent"><literal>NormGetNextEvent()</literal></link>
@ -194,7 +194,7 @@
number of concurrently active senders, this may translate to significant
memory allocation on receiver nodes. Currently, the API allows the
application to control how much buffer space is allocated for each
active sender (NOTE: In the future, API functions may be provided limit
active sender (NOTE: In the future, API functions may be provided to limit
the number of active senders monitored and/or provide the application
with finer control over receive buffer allocation, perhaps on a per
sender basis).</para>
@ -227,7 +227,7 @@
<title>Data Transmission</title>
<para>The behavior of data transport operation is largely placed in
the control of the NORM sender(s). NORM senders controls their data
the control of the NORM sender(s). NORM senders control their data
transmission rate, forward error correction (FEC) encoding settings,
and parameters controlling feedback from the receiver group. Multiple
senders may operate in a session, each with independent transmission
@ -253,7 +253,7 @@
be called before any calls to <link
linkend="NormStartReceiver"><literal>NormStartReceiver()</literal></link>
are made. However, note that the cache directory may be changed even
during active NORM reception. In this case, the new specified
during active NORM reception. In this case, the newly specified
directory path will be used for subsequently-received files. Any files
received before a directory path change will remain in the previous
cache location. Note that the <link
@ -477,15 +477,14 @@
Protokit. These are described below.</para>
<para>The "makefiles" directory contains Unix Makefiles for various
platforms the "win32" and "wince" sub-directories there contain Microsoft
platforms. The "win32" and "wince" sub-directories there contain Microsoft
Visual C++ (VC++) and Embedded VC++ project files for building the NORM
implementation. Additionally, a "waf" (Python-based build tool) build
option is supported that can be used to build and install the NORM library
code on the supported platforms. Finally, Python and Java bindings to the
NORM API are included and "src/python" and "src/java" directories contain
the code for these and the "makefiles/java" directory contains Makefiles
to build the NORM Java JNI bindings. Note the "waf" tool can also be used
to build the Java and Python bindings.</para>
NORM API are included in the "src/python" and "src/java" directories and the
"makefiles/java" directory contains Makefiles to build the NORM Java JNI bindings.
Note the "waf" tool can also be used to build the Java and Python bindings.</para>
<sect2>
<title>Unix Platforms</title>
@ -791,7 +790,7 @@
{
NormEventType type;
<link linkend="NormSessionHandle"><literal>NormSessionHandle</literal></link> session;
<link linkend="NormNodeHandle"><literal>NormNodeHandle</literal></link> node;
<link linkend="NormNodeHandle"><literal>NormNodeHandle</literal></link> sender;
<link linkend="NormObjectHandle"><literal>NormObjectHandle</literal></link> object;
} <link linkend="NormEvent"><literal>NormEvent</literal></link>;</programlisting></para>
@ -801,7 +800,7 @@
all <link
linkend="NormEventType"><literal>NormEventType</literal></link> fields
are relevant to all events. The <parameter>session</parameter>,
<parameter>node</parameter>, and <parameter>object</parameter> fields
<parameter>sender</parameter>, and <parameter>object</parameter> fields
indicate the applicable <link
linkend="NormSessionHandle"><literal>NormSessionHandle</literal></link>,
<link

0
doc/NormLogo.gif Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

0
doc/NormUserGuide.pdf Normal file → Executable file
View File

22
doc/NormUserGuide.xml Normal file → Executable file
View File

@ -96,11 +96,13 @@
<orderedlist>
<listitem>
<para>Download and unpack the NORM source code tarball.</para>
<para>Download and unpack the NORM source code tarball or clone the github
repository using
<literal>git clone --recurse-submodules https://github.com/USNavalResearchLaboratory/norm.git</literal></para>
</listitem>
<listitem>
<para><literal>cd norm/unix</literal></para>
<para><literal>cd norm/makefiles</literal></para>
</listitem>
<listitem>
@ -118,7 +120,8 @@
<orderedlist>
<listitem>
<para>Download and unpack the NORM source code tarball</para>
<para>Download and unpack the NORM source code tarball or clone the
repository as described in the section above.</para>
</listitem>
<listitem>
@ -128,7 +131,7 @@
</listitem>
<listitem>
<para>Open the "<filename>norm.sln</filename>" (VC++ .Net),
<para>Inside the "<filename>norm/makefiles/win32</filename>" directory, open the "<filename>norm.sln</filename>" (VC++ .Net),
"<filename>norm.dsw</filename>" (VC++ 6.0), or
"<filename>norm.vcw</filename>" (Embedded VC++) workspace
file.</para>
@ -137,9 +140,14 @@
<listitem>
<para>The "<emphasis>norm</emphasis>" project can be selected and
built.  The "<filename>norm.exe</filename>" file will be found in
the "<filename>norm/win32/norm/Release</filename>" directory.</para>
the "<filename>norm/Win32/norm/Release</filename>" directory.</para>
</listitem>
</orderedlist>
<para>The easiest way to run these builds is with Visual Studio. If you do not already have Visual Studio installed, then it can
be downloaded for free <ulink url="https://visualstudio.microsoft.com/downloads/?cid=learn-onpage-download-cta">here</ulink>.
When you launch Visual Studio, make sure to select "Visual C++" and open the "<filename>norm.sln</filename>" file.
This should load all of the project files and allow you to right-click on any of them in the Solution Explorer on the
left side and select "build".</para>
</sect2>
</sect1>
@ -380,7 +388,7 @@
<para>A minimal example <emphasis>norm</emphasis> sender command-line
syntax is:</para>
<para><literal>norm addr &lt;addr/port&gt; sendFile
<para><literal>norm addr &lt;addr/port&gt; sendfile
&lt;fileName&gt;</literal></para>
<para>The corresponding minimal <emphasis>norm</emphasis> receiver
@ -1160,4 +1168,4 @@
use with norm</emphasis>
</para>
</appendix>
</article>
</article>

0
doc/npcUsage.pdf Normal file → Executable file
View File

BIN
doc/npcUserGuide.pdf Normal file

Binary file not shown.

413
doc/npcUserGuide.xml Normal file
View File

@ -0,0 +1,413 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<article lang="">
<articleinfo>
<title><inlinemediaobject>
<imageobject>
<imagedata align="center" fileref="NormLogo.gif" scale="50"/>
</imageobject>
</inlinemediaobject> <command>npc</command> User Guide</title>
<subtitle>(NORM Precoder User Guide)</subtitle>
<titleabbrev><command>npc</command> User Guide</titleabbrev>
</articleinfo>
<sect1>
<title>Background</title>
<para>The NACK-Oriented Reliable Multicast (NORM) protocol is capable of
supporting robust transmission of content to "silent" receivers that are
required or only capable of operating in an emission-controlled (EMCON)
manner. This capability is enabled when the NORM sender is configured to
proactively transmit Forward Error Correction (FEC) erasure coding content
as part of its original data transmission. For NACK-based operation, the
FEC repair packets are usually sent only reactively, in response to repair
requests (NACKs) from the receiver group. However, hybrid operation with a
combination of proactive FEC content and additional reactive FEC repairs
as needed is also supported. Similarly, a mix of nacking and silent
receivers may be supported with silent receivers capitalizing on the FEC
repair information sent proactively and/or reactively. The purpose of the
NORM Pre-Coder (<command>npc</command>) software utility described here is
to support additional robustness for purely-proactive sessions, where the
receivers are unable to request repair or retransmission of
content.</para>
<para>The Naval Research Laboratory (NRL) reference implementation of the
NORM protocol includes support for 8-bit and 16-bit Reed-Solomon FEC
encoding with additional support for other coding algorithms (e.g.,
Low-Density Parity Check (LDPC)) planned for the future. The NORM
specification allows for different FEC algorithms to be applied within the
protocol. The current Reed-Solomon NORM FEC algorithms in the NRL
implementation are limited to modest code block sizes (With 16-bit
Reed-Solomon coding, larger block sizes will be allowed but very high data
rates may not be possible). For channels with random errors, the current
NORM FEC codecs are often adequate as there is flexibility in how the
encoded data can be partitioned into FEC blocks (a block consists of some
number of data segments (packets)) and the number of FEC parity packets
that can computed and possibly transmitted per source data block. For
channels with large bursts of packet loss (with respect to the configured
NORM FEC block size), it is quite possible that the number of lost packets
(erasures) that occur within a NORM FEC block may exceed the configured
erasure-filling capability. The <command>npc</command> utility was created
to "pre-encode" (and "post-decode") files for NORM transmission to silent
(non- NACKing) receivers by adding additional FEC encoding, and
importantly, interleaving of the FEC segments (packets) to re-distribute
bursts of packet losses as random losses over the entire file. It is thus
most applicable to very large files (with respect to FEC block
sizes).</para>
<para>The NORM protocol is described in Internet Engineering Task Force
(IETF) Request For Comments (RFC) RFC 5740 and RFC 5741. NRL provides a
NORM protocol library with a well-defined API that it is suitable for
application development. Refer to the NORM website &lt;<ulink
url="https://github.com/USNavalResearchLaboratory/norm">https://github.com/USNavalResearchLaboratory/norm</ulink>&gt;
for these other components as well as up-to-date versions of this
demonstration application and documentation.</para>
<para>The <command>npc</command> tool is designed to use in conjunction
with the NORM protocol and accompanying NORM file transfer examples that
are part of the NORM source code distribution. However, the encoded file
format that <command>npc</command> creates can be use with other
transports as well. The key is to align the segmentation parameters of the
<command>npc</command> configuration with that of the intended transport
mechanism.</para>
</sect1>
<sect1>
<title>Overview</title>
<para>The <command>npc</command> utility takes, as input", a file and
logically divides it into segments, adding cyclic-redundancy checksum
(CRC) to the segments, encoding the source segments with Reeed-Solomon
encoding (adding a configurable number of parity segments per FEC source
block), and interleaves the source and encoding segments to an output
file. The use of the CRC allows erasure to be detected and also provides
additional assurance of correct content delivery by possibly detecting bit
errors that may have been undetected during transport (i.e., link-layer
framing, Internet Protocol (IP), and/or User Datagram Protocol (UDP)
checksums). The interleaving by default is a block interleaver using the
entire file as a logical block, but a limit on the interleaving size can
be set to help increase the speed of the <command>npc</command>
encoding/decoding process. This may be useful for extremely large file
sizes.</para>
</sect1>
<sect1>
<title>Usage</title>
<para>The following is a synopsis of <command>npc</command> usage:</para>
<programlisting>npc {encode|decode} input &lt;inFile&gt; [output &lt;outFile&gt;][segment &lt;segmentSize&gt;]
{[[block &lt;numData&gt;][parity &lt;numParity&gt;]] |
[auto &lt;parityPercentage&gt;][bmax &lt;maxBlockSize&gt;]}
[imax &lt;widthLimit&gt;][ibuffer &lt;bytes&gt;][background][help][debug &lt;debugLevel&gt;]</programlisting>
<para>The <command>npc</command> utility may be instructed to either
"encode" a file (add FEC content and interleaving to the given
&lt;inFile&gt;) or "decode" a file that was previously encoded with
<command>npc</command>. The ".npc" file extension is suggested to
delineate files that are of the <command>npc</command> encoded format.
Note the "output" filename is optional. By default, <command>npc</command>
will use the filename of the &lt;inFile&gt; as the output filename,
replacing the '.' extension delimiter with a '_' (underscore) and adding
the ".npc" extension suffix. The <command>npc</command> format includes
some minimal "meta-data" in the first encoded &lt;segmentSize&gt; to
convey the file size and name of the original file. On decoding, if the
"output" file option is omitted, this "meta-data" is used to name the
decoded output file.</para>
<para>The optional FEC parameters,
<parameter>&lt;segmentSize&gt;</parameter>,
<parameter>&lt;numData&gt;</parameter>, and
<parameter>&lt;numParity&gt;</parameter> control the logical segmentation,
blocking, and amount of FEC parity content added to the file. For use with
NORM, it is recommended that the
<parameter>&lt;segmentSize&gt;</parameter> value correspond to the same
segmentation size used for NORM transmission. The
<parameter>&lt;numData&gt;</parameter> (source segments per FEC encoding
block) and <parameter>&lt;numParity&gt;</parameter> parameters should be
selected to provide erasure filling coverage for the expected transmission
packet loss characteristics. Note that when used with proactive NORM FEC
transmission, the <command>npc</command> encoding provides an "inner" FEC
code and interleaving and the NORM protocol provides an "outer" FEC
encoding. The "outer" NORM code might be configured to deal with typical
random packet loss due to channel BER, etc and the "inner"
<command>npc</command> interleaving and coding could be correspondingly
configured to handle expected burst losses (e.g. outages) that might
occur.</para>
<para>The <parameter>&lt;auto&gt;</parameter> option provides an
alternative means for setting the FEC encoding protection level instead of
using the <parameter>&lt;block&gt;</parameter> and
<parameter>&lt;parity&gt;</parameter> options. First the
<parameter>&lt;auto&gt;</parameter> option causes <command>npc</command>
to select a block size corresponding to the entire input file size (plus
the segment of meta data information that npc adds). Then, the
<parameter>&lt;auto&gt;</parameter> option
<parameter>&lt;parityPercentage&gt;</parameter> value is used to set the
number of parity packets per encoding block to the given percentage of the
automatically determined block size. For exanple, the command
"<option>auto 100"</option> causes <command>npc</command> to set an
encoding rate of 100%. I.e., the parity segments sent will equal the
number of segments in a bock. Note that the
<parameter>&lt;parityPercentage&gt;</parameter> can even exceed 100% if
desired for high levels of loss protection. Also note that the percentage
here is _not_ a loss protection percentage with a 100%
<parameter>&lt;parityPercentage&gt;</parameter> value being able to
correct up to 50% errored or lost packets within a coding block. With 50%
uniform random packet loss, this would result in successful file transfer
about 50% of the time as, per Gaussian distribution, burst error
probabilities would result in half of blocks arriving with greater than
50% packet loss and half with less than 50% packet loss.</para>
<para>When the <command>npc</command> encoder uses the
"<option>auto</option>" command the <command>npc</command> decoder MUST
also use the "<option>auto</option>" command and be configured with the
same <parameter>&lt;segmentSize&gt;</parameter> and
<parameter>&lt;parityPercentage&gt;</parameter> values. Similarly when the
"<option>block</option>" and "<option>parity</option>" commands are used
to explicitly set the <parameter>&lt;numdData&gt;</parameter> and
<parameter>&lt;numParity&gt;</parameter> at the encoder, the decoder MUST
be configured with the same corresponding options and values, again
including <parameter>&lt;segmentSize&gt;</parameter>. And for use with
NORM protocol transport, the <parameter>&lt;segmentSize&gt;</parameter>
parameter SHOULD be matched for best coding gain performance. The NORM
block size (numData) and parity (numParity) parameters may be set
indepedently. Basically, the NORM protocol proactive erasure coding can be
configured to deal with expected short term random packet loss while the
<command>npc</command> parameters can be configured to counter large burst
(or outage) losses. The inner/outer encoding approach that the combination
of <command>npc</command> and NORM provides, can allow for a sort of
multiplicative coding gain to deal well with both random packet loss and
bursts or outages with lower FEC overhead. However, when the
<command>npc</command> coding is configured (e.g., via the "auto" option)
to encapsulate an entire file into a single logical coding block, the
desired level of loss protection can be simply "dialed into" the
<command>npc</command> <parameter>&lt;parityPercentage&gt;</parameter>
option. The tradeoff is that the larger FEC block size increases the
computational requirement for file encoding and decoding. Future versions
of <command>npc</command> may provide additional FEC code types</para>
<para>As basic example usage, to encode a file name "originalFile.txt"
with the default <command>npc</command> naming convention, FEC, and
interleaving parameters, use the following syntax:</para>
<programlisting>npc encode input originalFile.txt</programlisting>
<para>This will produce and output file named
"<filename>originalFile_txt.npc</filename>" in the current working
directory. The default <command>npc</command> configuration is
"<command>auto 100.0</command>" providing 100% parity content which makes
the encoded file size roughly double the input file. The original file can
be recovered (decoded) using the syntax:</para>
<programlisting>npc decode input originalFile_txt.npc</programlisting>
<para>This will decode the ".npc" file, and in this case produce a file
named "<filename>originalFile.txt"</filename> in the current working
directory. (The file name information was stored in first "meta data"
segment of the ".npc" file). This default naming convention can be
overridden by using the <command>npc</command> "<option>output</option>"
command. For example, the syntax:</para>
<programlisting>npc decode input originalFile_txt.npc output file.txt</programlisting>
<para>will produce a file named "<filename>file.txt</filename>" that is
identical in content to "<filename>originalFile.txt</filename>".</para>
<sect2>
<title>Notes</title>
<para>The FEC and interleaving parameters that are used for
<command>npc</command> encoding MUST be exactly matched to successfully
decode the encoded file. I.e., if the defaults are used for encoding,
the defaults must be used for decoding. The parameters that must match
include <parameter>&lt;segmentSize&gt;</parameter>,
<parameter>&lt;parityPercentage&gt;</parameter> and
<parameter>&lt;maxBlockSize&gt;</parameter> (or
<parameter>&lt;numData&gt;</parameter> and
<parameter>&lt;numParity&gt;</parameter>), and
<parameter>&lt;widthMax&gt;</parameter>.</para>
<para>It is possible that in some cases it may be beneficial to apply
more proactive FEC content with the <command>npc</command> program
instead of with the NORM transport. The trade-offs are
scenario-specific.</para>
<para>The NRL "<command>norm</command>" demonstration application has
commands included to support transport of <command>npc</command> encoded
files. The distinction here is that a file that _fails_ NORM transport
might still be successfully decoded with <command>npc</command>. There
are two receiver-side <command>norm</command> demo application options
that apply here:</para>
<orderedlist>
<listitem>
<para>The "<option>saveAborts</option>" command causes
<command>norm</command> to not delete (and attempt to postprocess)
"aborted" files (files that failed reliable NORM transport).</para>
</listitem>
<listitem>
<para>The <command>norm</command> "<option>lowDelay</option>"
command should be applied for silent-receivers to more immediately
deliver "failed" files to the application for post-processing (i.e.,
attempted <command>npc</command> decoding)</para>
</listitem>
</orderedlist>
</sect2>
</sect1>
<sect1>
<title><command>npc</command> Command Reference</title>
<para>The following table describes each of the <command>npc</command>
commands available in the command-line syntax.</para>
<informaltable frame="all">
<tgroup cols="2">
<colspec colnum="1" colwidth="1*"/>
<colspec colname="2" colwidth="2*"/>
<tbody>
<row>
<entry><para><option>encode</option> |
<option>decode</option></para></entry>
<entry><para>Determine whether <command>npc</command> is to encode
or decode the given <parameter>&lt;inFile&gt;</parameter>. This
option is required and only one should be given.</para></entry>
</row>
<row>
<entry><para><option>input
</option><parameter>&lt;inFile&gt;</parameter></para></entry>
<entry><para>Specifies the file to be processed. Required
command.</para></entry>
</row>
<row>
<entry><para><option>output
</option><parameter>&lt;outFile&gt;</parameter></para></entry>
<entry><para>Specifies the name of the output file to be produced.
Overrides the default <command>npc</command> output file naming
convention. Optional.</para></entry>
</row>
<row>
<entry><para><option>segment
</option><parameter>&lt;segmentSize&gt;</parameter></para></entry>
<entry><para>Sets the segmentation size (e.g., packet payload
size) in bytes. Note four bytes of the
<parameter>&lt;segmentSize&gt;</parameter> are used for a 32-bit
CRC that <command>npc</command> applies to each segment. (Default
<parameter>&lt;segmentSize&gt;</parameter> is 1024
bytes)</para></entry>
</row>
<row>
<entry><para><option>block
</option><parameter>&lt;numData&gt;</parameter></para></entry>
<entry><para>Specify the number of source data segments (packets)
per <command>npc</command> FEC coding block. (Default block sizing
is auto)</para></entry>
</row>
<row>
<entry><para><option>parity
</option><parameter>&lt;numParity&gt;</parameter></para></entry>
<entry><para>Specify the number of FEC parity segments (packets)
added per <command>npc</command> FEC coding block. (Default is 2
segments).</para></entry>
</row>
<row>
<entry><para><option>auto
</option><parameter>&lt;parityPercentage&gt;</parameter></para></entry>
<entry><para>Specifies automatic FEC block sizing with
<parameter>&lt;parityPercentage&gt;</parameter> indicating the
percentage of FEC parity segments to include per block. The "auto"
block sizing sets the block size as large as possible to treat the
entire files as one logical FEC block to maximize FEC performance.
The maximum possible block size currently supported by
<command>npc</command> are blocks where (numData + numParity) is
less than or equal to 65536. The maximum buffer size can be
limited by using the <option>bmax</option> command.</para></entry>
</row>
<row>
<entry><para><option>bmax
</option><parameter>&lt;maxBlockSize&gt;</parameter></para></entry>
<entry><para>Limits the maximum block size when the
<option>auto</option> command is used for automatic block sizing
(Default is 65536)</para></entry>
</row>
<row>
<entry><para><option>imax
</option><parameter>&lt;widthMax&gt;</parameter></para></entry>
<entry><para>Limits interleaving of encoded file to a maximum
interleaver width of <parameter>&lt;widthMax&gt;</parameter>
segments. A value of ZERO (or less) defaults to
<command>npc</command> calculating a block interleaver that
encompasses the entire encoded file size. For extremely large
files, this option may be beneficial to limit file seeking
operations required to interleave the file. If the encoded file
size is less than
<parameter>&lt;widthMax&gt;</parameter>*<parameter>&lt;widthMax&gt;</parameter>
segments, <command>npc</command> will again calculate its own
maximum block size. (Default is 1000 segments interleaver depth
(i.e., about 1 Gbyte interleaver size with the default 1024 byte
<parameter>&lt;segmentSize&gt;</parameter> value))</para></entry>
</row>
<row>
<entry><para><option>ibuffer
</option><parameter>&lt;bufferSize&gt;</parameter></para></entry>
<entry><para>This sets the maximum memory (in bytes) that
<command>npc</command> allocates for encoding. A larger value
allows <command>npc</command> to perform file input/output with
less seeking and improved encoding/decoding times can be achieved.
(Default is 1.5 GByte)</para></entry>
</row>
<row>
<entry><para><option>debug
</option><parameter>&lt;debugLevel&gt;</parameter></para></entry>
<entry><para>Specifies debug output verbosity. Higher number is
more verbose debugging information. (Default is
ZERO).</para></entry>
</row>
<row>
<entry><para><option>background</option></para></entry>
<entry><para>Sets percentage of received messages that are
randomly dropped (for testing purposes). Default = 0.0
percent.</para></entry>
</row>
<row>
<entry><para><option>help</option></para></entry>
<entry><para>Displays <command>npc</command> usage
statement.</para></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</sect1>
</article>

7
docker/run.sh Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -e
echo Running example $@
exec "$NORM_BUILD/$@"

59
docker/setup.sh Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env bash
set -eux
install_debian()
{
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -yq \
python2.7 \
g++ \
libxml2-dev \
libnetfilter-queue-dev
ln -s /usr/bin/python2.7 /usr/bin/python
if [ "$VERSION" != "" ]; then
apt-get install -yq git-core
cd $NORM_DIR && git checkout $VERSION && git submodule update --checkout --init --force
fi
if [[ "$WAF_CONFIGURE" =~ "java" && -z `which java` ]]; then
apt-get install -yq default-jdk-headless
export JAVA_HOME=$(readlink -f `which java` | sed 's/\/bin\/java//')
fi
}
install_redhat()
{
yum update -y
yum install -y \
which \
centos-release-scl
yum install -y \
gcc-c++ \
libxml2-devel \
libnetfilter_queue-devel
if [ "$VERSION" != "" ]; then
yum install -y git
cd $NORM_DIR && git checkout $VERSION && git submodule update --checkout --init --force
fi
if [[ "$WAF_CONFIGURE" =~ "java" && -z `which java` ]]; then
yum install -y java-1.8.0-openjdk-devel
export JAVA_HOME=$(readlink -f `which java` | sed 's/\/jre\/bin\/java//')
fi
}
configure_norm()
{
cd $NORM_DIR && ./waf configure ${WAF_CONFIGURE}
}
if [ ! -z `which apt` ]; then
install_debian
elif [ ! -z $(which yum) ] || [ "$?" = "1" ]; then
install_redhat
fi
configure_norm

0
examples/README.TXT Normal file → Executable file
View File

1424
examples/chant.cpp Executable file

File diff suppressed because it is too large Load Diff

0
examples/java/NormFileRecv.java Normal file → Executable file
View File

0
examples/java/NormFileSend.java Normal file → Executable file
View File

0
examples/java/NormFileSendRecv.java Normal file → Executable file
View File

0
examples/java/NormMsgr.java Normal file → Executable file
View File

0
examples/java/NormStreamRecv.java Normal file → Executable file
View File

4
examples/java/NormStreamSend.java Normal file → Executable file
View File

@ -10,8 +10,8 @@ public class NormStreamSend {
static final long REPAIR_WINDOW_SIZE = 1024 * 1024;
static final long SESSION_BUFFER_SIZE = 1024 * 1024;
static final int SEGMENT_SIZE = 1400;
static final int BLOCK_SIZE = 64;
static final int PARITY_SEGMENTS = 16;
static final short BLOCK_SIZE = 64;
static final short PARITY_SEGMENTS = 16;
static final String DEST_ADDRESS = "224.1.2.3";
static final int DEST_PORT = 6003;

0
examples/java/README.TXT Normal file → Executable file
View File

523
examples/normCast.cpp Normal file → Executable file
View File

@ -1,5 +1,6 @@
#include "normApi.h"
#include "normPostProcess.h"
#include <stdio.h> // for printf(), etc
#include <stdlib.h> // for atoi(), etc
#include <cassert>
@ -48,6 +49,7 @@
#include "protoFile.h" // for ProtoFile::PathList and iterator for tx file/directory queue
#include "protoString.h" // for ProtoTokenator
#include "protoAddress.h" // for ProtoAddress
#include "protoTime.h" // for ProtoTime
class NormCaster
{
@ -59,6 +61,7 @@ class NormCaster
enum CCMode {NORM_FIXED, NORM_CC, NORM_CCE, NORM_CCL};
void Destroy();
bool Init();
bool OpenNormSession(NormInstanceHandle instance,
const char* addr,
@ -70,6 +73,12 @@ class NormCaster
void SetNormCongestionControl(CCMode ccMode);
void SetGrttEstimate(double grtt_estimate)
{
assert(NORM_SESSION_INVALID != norm_session);
assert(grtt_estimate > 0);
NormSetGrttEstimate(norm_session, grtt_estimate);
}
void SetNormTxRate(double bitsPerSecond)
{
assert(NORM_SESSION_INVALID != norm_session);
@ -80,6 +89,14 @@ class NormCaster
assert(NORM_SESSION_INVALID != norm_session);
NormSetMulticastInterface(norm_session, ifaceName);
}
bool SetNormTxPort(UINT16 txPort,
bool enableReuse,
const char* txAddress)
{
assert(NORM_SESSION_INVALID != norm_session);
return NormSetTxPort(norm_session, txPort, enableReuse, txAddress);
}
void SetLoopback(bool state)
{
loopback = state;
@ -110,8 +127,18 @@ class NormCaster
void HandleNormEvent(const NormEvent& event);
void HandleTimeout();
// Sender methods
bool AddTxItem(const char* path);
void SetRepeat(double interval, bool updatesOnly)
{
repeat_interval = interval;
tx_file_iterator.SetUpdatesOnly(updatesOnly); // TBD - add option to send new files only
}
double GetTimerDelay() const
{return timer_delay;}
bool StageNextTxFile();
bool TxFilePending()
{return '\0' != tx_pending_path[0];}
@ -130,7 +157,11 @@ class NormCaster
void SetNumParity(unsigned short numParity)
{num_parity = numParity;}
void SetAutoParity(unsigned short autoParity)
{auto_parity = autoParity;}
{
auto_parity = autoParity;
if (norm_session != NORM_SESSION_INVALID)
NormSetAutoParity(norm_session, auto_parity < num_parity ? auto_parity : num_parity);
}
// Receiver methods
void SetRxCacheDirectory(const char* path)
@ -148,6 +179,14 @@ class NormCaster
{return rx_cache_path;}
void SetRxSocketBufferSize(unsigned int value)
{rx_socket_buffer_size = value;}
bool SetPostProcessorCommand(const char* cmd)
{return post_processor->SetCommand(cmd);}
bool SetSentProcessorCommand(const char* cmd)
{return sent_processor->SetCommand(cmd);}
bool SetPurgedProcessorCommand(const char* cmd)
{return purged_processor->SetCommand(cmd);}
void SaveAborts(bool save_aborts)
{save_aborted_files = save_aborts;}
// These can only be called post-OpenNormSession()
@ -158,24 +197,49 @@ class NormCaster
norm_acking = enable;
}
void SetSilentReceiver(bool state)
{NormSetSilentReceiver(norm_session, state);}
{
assert(NORM_SESSION_INVALID != norm_session);
NormSetSilentReceiver(norm_session, state);
}
void SetProbeTOS(UINT8 value)
{probe_tos = value;}
void SetProbeMode(NormProbingMode mode)
{probe_mode = mode;}
void SetTxLoss(double txloss)
{NormSetTxLoss(norm_session, txloss);}
{
assert(NORM_SESSION_INVALID != norm_session);
assert(0 <= txloss);
NormSetTxLoss(norm_session, txloss);
}
void SetRxLoss(double rxloss)
{
assert(NORM_SESSION_INVALID != norm_session);
assert(0 <= rxloss);
NormSetRxLoss(norm_session, rxloss);
}
private:
bool is_running;
NormSessionHandle norm_session;
NormPostProcessor* post_processor;
NormPostProcessor* sent_processor;
NormPostProcessor* purged_processor;
bool save_aborted_files;
ProtoFile::PathList tx_file_list;
ProtoFile::PathList::PathIterator tx_file_iterator;
char tx_pending_path[PATH_MAX + 1];
unsigned int tx_pending_prefix_len;
double repeat_interval;
double timer_delay; // currently tracks the repeat timeout only
ProtoTime timer_start; // used to mark timer start time
bool is_multicast;
bool loopback;
UINT8 probe_tos;
NormProbingMode probe_mode;
unsigned int norm_tx_queue_max; // max number of objects that can be enqueued at once
unsigned int norm_tx_queue_count; // count of unacknowledged enqueued objects (TBD - optionally track size too)
bool norm_flow_control_pending;
@ -203,8 +267,10 @@ class NormCaster
}; // end class NormCaster
NormCaster::NormCaster()
: norm_session(NORM_SESSION_INVALID), tx_file_iterator(tx_file_list),
tx_pending_prefix_len(0), is_multicast(false), loopback(false), probe_tos(0),
: norm_session(NORM_SESSION_INVALID), post_processor(NULL), sent_processor(NULL),
purged_processor(NULL), save_aborted_files(false), tx_file_iterator(tx_file_list),
tx_pending_prefix_len(0), repeat_interval(-1.0), timer_delay(-1.0),
is_multicast(false), loopback(false), probe_tos(0), probe_mode(NORM_PROBE_ACTIVE),
norm_tx_queue_max(8), norm_tx_queue_count(0),
norm_flow_control_pending(false), norm_tx_vacancy(true), norm_acking(false),
norm_flushing(true), norm_flush_object(NORM_OBJECT_INVALID), norm_last_object(NORM_OBJECT_INVALID),
@ -226,14 +292,47 @@ NormCaster::~NormCaster()
void NormCaster::Destroy()
{
tx_file_list.Destroy();
if (post_processor)
{
delete post_processor;
post_processor = NULL;
}
if (sent_processor)
{
delete sent_processor;
sent_processor = NULL;
}
if (purged_processor)
{
delete purged_processor;
purged_processor = NULL;
}
}
bool NormCaster::Init()
{
if (!(post_processor = NormPostProcessor::Create()))
{
fprintf(stderr, "normCast error: unable to create post processor\n");
return false;
}
if (!(sent_processor = NormPostProcessor::Create()))
{
fprintf(stderr, "normCast error: unable to create sent processor\n");
return false;
}
if (!(purged_processor = NormPostProcessor::Create()))
{
fprintf(stderr, "normCast error: unable to create purged processor\n");
return false;
}
return true;
}
bool NormCaster::AddTxItem(const char* path)
{
bool result = tx_file_list.AppendPath(path);
if (!result)
perror("NormCaster::AddTxItem() error");
if (!TxFilePending()) StageNextTxFile();
if (!result) perror("NormCaster::AddTxItem() error");
return result;
} // end NormCaster::AddTxItem()
@ -271,7 +370,8 @@ bool NormCaster::OpenNormSession(NormInstanceHandle instance, const char* addr,
//NormSetTxRobustFactor(norm_session, 20);
NormSetGrttProbingTOS(norm_session, probe_tos);
NormSetGrttProbingTOS(norm_session, probe_tos); // this was for some experimental protocol work
NormSetGrttProbingMode(norm_session, probe_mode);
return true;
} // end NormCaster::OpenNormSession()
@ -332,10 +432,9 @@ bool NormCaster::Start(bool sender, bool receiver)
}
else
{
// Uncommant and adjust this for more/less robust timer-based flow control as desired
// Uncomment and adjust this for more/less robust timer-based flow control as desired (API default: 2.0)
//NormSetFlowControl(norm_session, 10.0);
}
NormSetGrttEstimate(norm_session, 0.001);
//NormSetGrttMax(norm_session, 0.100);
NormSetBackoffFactor(norm_session, 0);
@ -351,6 +450,8 @@ bool NormCaster::Start(bool sender, bool receiver)
NormSetAutoParity(norm_session, auto_parity < num_parity ? auto_parity : num_parity);
if (0 != tx_socket_buffer_size)
NormSetTxSocketBuffer(norm_session, tx_socket_buffer_size);
}
is_running = true;
return true;
@ -379,6 +480,7 @@ bool NormCaster::TxReady() const
bool NormCaster::StageNextTxFile()
{
// Pull next file path from "tx_file_list" and stage as "tx_pending_path"
tx_pending_path[0] = '\0';
if (tx_file_iterator.GetNextFile(tx_pending_path))
{
// This code omits the source directory prefix from the name transmitted
@ -408,13 +510,42 @@ bool NormCaster::StageNextTxFile()
}
else
{
// Either done need to reset tx_file_iterator
// Either done or need to reset tx_file_iterator
tx_pending_path[0] = '\0';
tx_pending_prefix_len = 0;
// We have reached end of tx_file_list, so either
// we're done or we reset tx_file_iterator (when 'repeat' option (TBD) is enabled)
if (repeat_interval >= 0.0)
{
timer_start.GetCurrentTime();
timer_delay = repeat_interval;
tx_file_iterator.Reset();
}
return false;
}
} // end NormCaster::StageNextTxFile()
void NormCaster::HandleTimeout()
{
if (timer_delay < 0.0) return; // no timeout pending
ProtoTime currentTime;
currentTime.GetCurrentTime();
double elapsedTime = currentTime - timer_start;
if (elapsedTime >= timer_delay)
{
// Timer has expired.(currently repeat_interval is only timeout)
timer_delay = -1.0;
if (StageNextTxFile())
SendFiles();
// else repeat timer was reset
}
else
{
timer_delay -= elapsedTime;
}
} // end NormCaster::HandleTimeout()
void NormCaster::SendFiles()
{
// Send pending file and subsequent files from tx_file_iterator as available/possible
@ -429,8 +560,6 @@ void NormCaster::SendFiles()
// Get next file name from our "tx_file_list"
if (!StageNextTxFile())
{
// We have reach end of tx_file_list, so either
// we're done or we reset tx_file_iterator (when 'repeat' option (TBD) is enabled)
// If we're done and requesting ACK, finish up nicely with final waterrmark
if (norm_acking)
{
@ -457,7 +586,9 @@ bool NormCaster::EnqueueFileObject()
{
assert(norm_tx_queue_count < norm_tx_queue_max);
if (norm_tx_queue_count >= norm_tx_queue_max)
{
return false;
}
}
// This is our cheesy approach of using the NORM_INFO to convey the file name
@ -484,7 +615,7 @@ bool NormCaster::EnqueueFileObject()
NormObjectHandle object = NormFileEnqueue(norm_session, tx_pending_path, nameInfo, nameLen);
if (NORM_OBJECT_INVALID == object)
{
// This might happen if a non-acking receiver is present and
// This might happen if a non-acking receiver is present and
// has nacked for the oldest object in the queue even if all
// of our acking receivers have acknowledged it.
//fprintf(stderr, "NO VACANCY count:%u max:%u\n", norm_tx_queue_count, norm_tx_queue_max);
@ -494,7 +625,7 @@ bool NormCaster::EnqueueFileObject()
fprintf(stderr, "normCast: enqueued \"%s\" for transmission ...\n", namePtr);
if (norm_acking)
{
// ack-based flow control has been enabled
// ack-based flow control has been enabled
norm_tx_queue_count++;
if (!norm_flow_control_pending && (norm_tx_queue_count >= (norm_tx_queue_max / 2)))
{
@ -533,6 +664,7 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
{
case NORM_TX_QUEUE_EMPTY:
case NORM_TX_QUEUE_VACANCY:
//fprintf(stderr, "normCast: NORM_TX_QUEUE EMPTY/VACANCY\n");
norm_tx_vacancy = true;
if (TxFilePending()) SendFiles();
break;
@ -542,8 +674,10 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
break;
case NORM_TX_WATERMARK_COMPLETED:
{
if (NORM_ACK_SUCCESS == NormGetAckingStatus(norm_session))
{
fprintf(stderr, "normCast: NORM_TX_WATERMARK_COMPLETED, NORM_ACK_SUCCESS\n");
// All receivers acknowledged.
norm_last_object = NORM_OBJECT_INVALID;
bool txFilePending = TxFilePending(); // need to check this _before_ possible call to SendFiles()
@ -569,7 +703,7 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
}
else
{
fprintf(stderr, "normCast: NORM_TX_WATERMARK_COMPLETED, _NOT_ NORM_ACK_SUCCESS\n");
// In multicast, there is a chance some nodes ACK ...
// so let's see who did, if any.
// This iterates through the acking nodes looking for responses
@ -582,7 +716,7 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
ProtoAddress addr;
addr.SetRawHostAddress(ProtoAddress::IPv4, (char*)&tmp, 4);
if (NORM_ACK_SUCCESS != ackingStatus)
fprintf(stderr, "normCast: node %lu (IP address: %s) failed to acnowledge.\n",
fprintf(stderr, "normCast: node %lu (IP address: %s) failed to acnkowledge.\n",
(unsigned long)nodeId, addr.GetHostString());
else
fprintf(stderr, "normCast: node %lu (IP address: %s) acknowledged.\n",
@ -595,7 +729,7 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
{
NormResetWatermark(norm_session);
}
else // might as request ack for most recent enqueued object
else // might as well request ack for most recent enqueued object (not sure why I did this?)
{
NormSetWatermark(norm_session, norm_flush_object, true);
norm_last_object = norm_flush_object;
@ -603,16 +737,62 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
}
}
break;
}
case NORM_TX_FLUSH_COMPLETED:
{
fprintf(stderr, "normCast: NORM_TX_FLUSH_COMPLETED\n");
if (!TxFilePending() && (repeat_interval < 0.0)&& !norm_acking)
{
// No more files to send, and not ack or repeat mode
fprintf(stderr, "normCast: flush after final file send, exiting ...\n");
is_running = false;
}
break;
}
case NORM_TX_OBJECT_PURGED:
{
if(event.object == norm_flush_object)
norm_flush_object = NORM_OBJECT_INVALID;
if (NORM_OBJECT_FILE != NormObjectGetType(event.object))
{
fprintf(stderr, "normCast: purged invalid object type?!\n");
break;
}
char fileName[PATH_MAX + 1];
fileName[PATH_MAX] = '\0';
NormFileGetName(event.object, fileName, PATH_MAX);
fprintf(stderr, "normCast: send file purged: \"%s\"\n", fileName);
// This is where we could delete the associated tx file if desired
// (e.g., for an "outbox" use case)
if (purged_processor->IsEnabled())
{
if (!purged_processor->ProcessFile(fileName))
fprintf(stderr, "normCast: purged processing error\n");
}
break;
}
case NORM_TX_OBJECT_SENT:
{
if (NORM_OBJECT_FILE != NormObjectGetType(event.object))
{
fprintf(stderr, "normCast: sent invalid object type?!\n");
break;
}
char fileName[PATH_MAX + 1];
fileName[PATH_MAX] = '\0';
NormFileGetName(event.object, fileName, PATH_MAX);
fprintf(stderr, "normCast: initial send complete for \"%s\"\n", fileName);
if (sent_processor->IsEnabled())
{
if (!sent_processor->ProcessFile(fileName))
fprintf(stderr, "normCast: sent processing error\n");
}
break;
}
case NORM_ACKING_NODE_NEW:
{
NormNodeId id = NormNodeGetId(event.sender);
@ -620,6 +800,8 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
ProtoAddress addr;
addr.SetRawHostAddress(ProtoAddress::IPv4, (char*)&tmp, 4);
fprintf(stderr, "normCast: new acking node: %lu (IP address: %s)\n", (unsigned long)id, addr.GetHostString());
// This next line of code updates the current watermark request (if there is one) so the new acking node is included
NormResetWatermark(norm_session);
}
case NORM_REMOTE_SENDER_INACTIVE:
@ -628,9 +810,33 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
break;
case NORM_RX_OBJECT_ABORTED:
{
//fprintf(stderr, "NORM_RX_OBJECT_ABORTED\n");// %hu\n", NormObjectGetTransportId(event.object));
if (NORM_OBJECT_FILE != NormObjectGetType(event.object))
{
fprintf(stderr, "normCast: received invalid object type?!\n");
break;
}
char fileName[PATH_MAX + 1];
fileName[PATH_MAX] = '\0';
NormFileGetName(event.object, fileName, PATH_MAX);
fprintf(stderr, "normCast: aborted reception of \"%s\"\n", fileName);
if (save_aborted_files)
{
if (post_processor->IsEnabled())
{
if (!post_processor->ProcessFile(fileName))
fprintf(stderr, "normCast: post processing error\n");
}
}
else
{
if (remove(fileName) != 0)
fprintf(stderr, "normCast: error deleting aborted file \"%s\"\n", fileName);
}
break;
}
case NORM_RX_OBJECT_INFO:
{
// We use the NORM_INFO to contain the transferred file name
@ -670,7 +876,11 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
fileName[PATH_MAX] = '\0';
NormFileGetName(event.object, fileName, PATH_MAX);
fprintf(stderr, "normCast: completed reception of \"%s\"\n", fileName);
// TBD - implement receive post processing option ...
if (post_processor->IsEnabled())
{
if (!post_processor->ProcessFile(fileName))
fprintf(stderr, "normCast: post processing error\n");
}
break;
}
@ -683,13 +893,19 @@ void NormCaster::HandleNormEvent(const NormEvent& event)
void Usage()
{
fprintf(stderr, "Usage: normCast id <nodeIdInteger> {send <file/dir list> &| recv <rxCacheDir>}\n"
" [addr <addr>[/<port>]] [interface <name>] [loopback]\n"
fprintf(stderr, "Usage: normCast {send <file/dir list> &| recv <rxCacheDir>} [silent {on|off}]\n"
" [repeat <interval> [updatesOnly]] [id <nodeIdInteger>]\n"
" [addr <addr>[/<port>]][txaddr <addr>[/<port>]][txport <port>]\n"
" [interface <name>][reuse][loopback]\n"
" [ack auto|<node1>[,<node2>,...]] [segment <bytes>]\n"
" [block <count>] [parity <count>] [auto <count>]\n"
" [cc|cce|ccl|rate <bitsPerSecond>] [ptos <value>]\n"
" [flush {none|passive|active}] [silent] [txloss <lossFraction>]\n"
" [buffer <bytes>] [txsockbuffer <bytes>] [rxsockbuffer <bytes>]\n"
" [cc|cce|ccl|rate <bitsPerSecond>] [rxloss <lossFraction>]\n"
" [txloss <lossFraction>] [flush {none|passive|active}]\n"
" [grttprobing {none|passive|active}] [grtt <secs>]\n"
" [ptos <value>] [processor <processorCmdLine>] [saveaborts]\n"
" [sentprocessor <processorCmdLine>]\n"
" [purgeprocessor <processorCmdLine>] [buffer <bytes>]\n"
" [txsockbuffer <bytes>] [rxsockbuffer <bytes>]\n"
" [debug <level>] [trace] [log <logfile>]\n");
} // end Usage()
@ -700,9 +916,17 @@ int main(int argc, char* argv[])
bool send = false;
bool recv = false;
double repeatInterval = -1.0;
bool updatesOnly = false;
char sessionAddr[64];
strcpy(sessionAddr, "224.1.2.3");
unsigned int sessionPort = 6003;
char sessionTxAddr[64];
sessionTxAddr[0] = '\0';
unsigned int sessionTxPort = 0;
bool autoAck = false;
NormNodeId ackingNodeList[256];
@ -718,9 +942,15 @@ int main(int argc, char* argv[])
bool trace = false;
bool silentReceiver = false;
double txloss = 0.0;
double rxloss = 0.0;
double grtt_estimate = 0.001;
NormProbingMode grtt_probing_mode = NORM_PROBE_ACTIVE;
bool loopback = false;
bool reuse = false;
NormCaster normCast;
if (!normCast.Init())
return -1;
// Parse command-line
int i = 1;
@ -751,6 +981,25 @@ int main(int argc, char* argv[])
}
send = true;
}
else if (0 == strncmp(cmd, "repeat", len))
{
if (i >= argc)
{
fprintf(stderr, "normCast error: missing 'repeat' <interval> value!\n");
Usage();
return -1;
}
if (1 != sscanf(argv[i++], "%lf", &repeatInterval))
{
fprintf(stderr, "normCast error: invalid repeat interval!\n");
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "updatesOnly", len))
{
updatesOnly = true;
}
else if (0 == strncmp(cmd, "recv", len))
{
if (i >= argc)
@ -819,6 +1068,58 @@ int main(int argc, char* argv[])
sessionPort = atoi(portPtr);
}
}
else if (0 == strncmp(cmd, "txaddr", len))
{
const char* addrPtr = argv[i++];
const char* portPtr = strchr(addrPtr, '/');
if (NULL == portPtr)
{
strncpy(sessionTxAddr, addrPtr, 63);
sessionTxAddr[63] = '\0';
}
else
{
size_t addrLen = portPtr - addrPtr;
if (addrLen > 63)
{
fprintf(stderr, "normCast error: 'txaddr' value too long!\n");
Usage();
return -1;
}
strncpy(sessionTxAddr, addrPtr, addrLen);
sessionTxAddr[addrLen] = '\0';
portPtr++;
int txPort = atoi(argv[i++]);
if ((txPort <=0) || (txPort > 0x0000ffff))
{
fprintf(stderr, "normCast error: invalid 'txport' value!\n");
Usage();
return -1;
}
sessionTxPort = txPort;
}
}
else if (0 == strncmp(cmd, "txport", len))
{
if (i >= argc)
{
fprintf(stderr, "normCast error: missing 'txport' value!\n");
Usage();
return -1;
}
int txPort = atoi(argv[i++]);
if ((txPort <=0) || (txPort > 0x0000ffff))
{
fprintf(stderr, "normCast error: invalid 'txport' value!\n");
Usage();
return -1;
}
sessionTxPort = txPort;
}
else if (0 == strncmp(cmd, "reuse", len))
{
reuse = true;
}
else if (0 == strncmp(cmd, "id", len))
{
if (i >= argc)
@ -888,6 +1189,7 @@ int main(int argc, char* argv[])
else
{
fprintf(stderr, "normCast error: invalid 'flush' mode \"%s\"\n", mode);
Usage();
return -1;
}
}
@ -1051,7 +1353,28 @@ int main(int argc, char* argv[])
}
else if (0 == strncmp(cmd, "silent", len))
{
silentReceiver = true;
// "on", or "off"
if (i >= argc)
{
fprintf(stderr, "normCast error: missing 'silent' <mode>!\n");
Usage();
return -1;
}
const char* mode = argv[i++];
if (0 == strcmp(mode, "on"))
{
silentReceiver = true;
}
else if (0 == strcmp(mode, "off"))
{
silentReceiver = false;
}
else
{
fprintf(stderr, "normCast error: invalid 'silent' mode \"%s\"\n", mode);
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "txloss", len))
{
@ -1062,6 +1385,53 @@ int main(int argc, char* argv[])
return -1;
}
}
else if (0 == strncmp(cmd, "rxloss", len))
{
if (1 != sscanf(argv[i++], "%lf", &rxloss))
{
fprintf(stderr, "normCast error: invalid 'rxloss' value!\n");
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "grtt", len))
{
if (1 != sscanf(argv[i++], "%lf", &grtt_estimate))
{
fprintf(stderr, "normCast error: invalid 'grtt' value!\n");
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "grttprobing", len))
{
// "none", "passive", or "active"
if (i >= argc)
{
fprintf(stderr, "normCast error: missing 'grttprobing' <mode>!\n");
Usage();
return -1;
}
const char* pmode = argv[i++];
if (0 == strcmp(pmode, "none"))
{
grtt_probing_mode = NORM_PROBE_NONE;
}
else if (0 == strcmp(pmode, "passive"))
{
grtt_probing_mode = NORM_PROBE_PASSIVE;
}
else if (0 == strcmp(pmode, "active"))
{
grtt_probing_mode = NORM_PROBE_ACTIVE;
}
else
{
fprintf(stderr, "normCast error: invalid 'grttprobing' mode \"%s\"\n", pmode);
return -1;
}
normCast.SetProbeMode(grtt_probing_mode);
}
else if (0 == strncmp(cmd, "debug", len))
{
if (i >= argc)
@ -1091,6 +1461,55 @@ int main(int argc, char* argv[])
Usage();
return 0;
}
else if (0 == strncmp(cmd, "processor", len))
{
if (i >= argc)
{
fprintf(stderr, "normCast error: missing 'processor' commandline!\n");
Usage();
return -1;
}
if (!normCast.SetPostProcessorCommand(argv[i++]))
{
fprintf(stderr, "normCast error: unable to set 'processor'!\n");
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "sentprocessor", len))
{
if (i >= argc)
{
fprintf(stderr, "normCast error: missing 'sentprocessor' commandline!\n");
Usage();
return -1;
}
if (!normCast.SetSentProcessorCommand(argv[i++]))
{
fprintf(stderr, "normCast error: unable to set 'sentprocessor'!\n");
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "purgeprocessor", len))
{
if (i >= argc)
{
fprintf(stderr, "normCast error: missing 'purgeprocessor' commandline!\n");
Usage();
return -1;
}
if (!normCast.SetPurgedProcessorCommand(argv[i++]))
{
fprintf(stderr, "normCast error: unable to set 'purgeprocessor'!\n");
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "saveaborts", len))
{
normCast.SaveAborts(true);
}
else
{
fprintf(stderr, "normCast error: invalid command \"%s\"!\n", cmd);
@ -1142,6 +1561,7 @@ int main(int argc, char* argv[])
if (silentReceiver) normCast.SetSilentReceiver(true);
if (txloss > 0.0) normCast.SetTxLoss(txloss);
if (rxloss > 0.0) normCast.SetRxLoss(rxloss);
if (autoAck)
@ -1159,13 +1579,27 @@ int main(int argc, char* argv[])
normCast.SetNormTxRate(txRate);
if (NULL != mcastIface)
normCast.SetNormMulticastInterface(mcastIface);
if ('\0' != sessionTxAddr[0])
normCast.SetNormTxPort(sessionTxPort, reuse, sessionTxAddr);
if (trace) normCast.SetNormMessageTrace(true);
normCast.SetRepeat(repeatInterval, updatesOnly);
// TBD - set NORM session parameters
normCast.Start(send, recv);
normCast.Start(send, recv);
normCast.SetGrttEstimate(grtt_estimate);
if (normCast.TxFilePending()) normCast.SendFiles();
if (send)
{
// This initiates repeat timer when there is no current files pending
//if ((repeatInterval >= 0.0) && !normCast.TxFilePending())
normCast.StageNextTxFile();
if (normCast.TxFilePending())
normCast.SendFiles();
}
#ifdef WIN32
//Win32InputHandler inputHandler;
@ -1188,12 +1622,16 @@ int main(int argc, char* argv[])
// (on Windows, would use the win32InputHandler code in norm/examples)
bool normEventPending = false;
bool inputEventPending = false;
double timerDelay = normCast.GetTimerDelay();
#ifdef WIN32
DWORD handleCount = inputNeeded ? 2 : 1;
DWORD msec = INFINITE;
if (timerDelay >= 0.0)
msec = (DWORD)(timerDelay*1000);
DWORD waitStatus =
MsgWaitForMultipleObjectsEx(handleCount, // number of handles in array
handleArray, // object-handle array
INFINITE, // time-out interval
msec, // time-out interval
QS_ALLINPUT, // input-event type
0);
if ((WAIT_OBJECT_0 <= waitStatus) && (waitStatus < (WAIT_OBJECT_0 + handleCount)))
@ -1219,12 +1657,17 @@ int main(int argc, char* argv[])
FD_SET(normfd, &fdsetInput);
//FD_SET(inputfd, &fdsetInput);
//if (inputfd > maxfd) maxfd = inputfd;
if (maxfd >= 0)
if ((maxfd >= 0) || (timerDelay >= 0.0))
{
struct timeval* timeoutPtr = NULL;
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int result = select(maxfd+1, &fdsetInput, NULL, NULL, NULL); //&timeout);
if (timerDelay >= 0.0)
{
timeout.tv_sec = (time_t)timerDelay;
timeout.tv_usec = (timerDelay - timeout.tv_sec)*1.0e+06;
timeoutPtr = &timeout;
}
int result = select(maxfd+1, &fdsetInput, NULL, NULL, timeoutPtr);
switch (result)
{
case -1:
@ -1253,10 +1696,10 @@ int main(int argc, char* argv[])
} // end if (maxfd >= 0)
#endif // if/else WIN32/UNIX
// if (inputEventPending)
// {
// TBD - could parse input for runtime commands (e.g., send <file>), etc
// }
if (inputEventPending)
{
// TBD - could parse input for runtime commands (e.g., send <file>), etc
}
if (normEventPending)
{
// Handle all pending NORM notification events
@ -1268,7 +1711,7 @@ int main(int argc, char* argv[])
normCast.HandleNormEvent(event);
}
}
// Invoke any 'timeout' actions here
normCast.HandleTimeout(); // checks for and acts on any pending timeout
} // end while(normCast.IsRunning()

1853
examples/normCastApp.cpp Executable file

File diff suppressed because it is too large Load Diff

0
examples/normClient.cpp Normal file → Executable file
View File

0
examples/normDataExample.cpp Normal file → Executable file
View File

0
examples/normDataRecv.cpp Normal file → Executable file
View File

0
examples/normDataSend.cpp Normal file → Executable file
View File

0
examples/normFileRecv.cpp Normal file → Executable file
View File

0
examples/normFileSend.cpp Normal file → Executable file
View File

16
examples/normMsgr.cpp Normal file → Executable file
View File

@ -202,6 +202,8 @@ class NormMsgr
{NormSetSilentReceiver(norm_session, state);}
void SetTxLoss(double txloss)
{NormSetTxLoss(norm_session, txloss);}
void SetRxLoss(double rxloss)
{NormSetRxLoss(norm_session, rxloss);}
private:
bool is_running;
@ -783,7 +785,8 @@ void Usage()
" [ack auto|<node1>[,<node2>,...]] [output <outFile>]\n"
" [cc|cce|ccl|rate <bitsPerSecond>] [interface <name>] [loopback]\n"
" [debug <level>] [trace] [log <logfile>] [silent]\n"
" [flush {none|passive|active}] [omit] [txloss <lossFraction>]\n");
" [flush {none|passive|active}] [omit] [txloss <lossFraction>]\n"
" [rxloss <lossFraction>]\n");
}
int main(int argc, char* argv[])
{
@ -811,6 +814,7 @@ int main(int argc, char* argv[])
bool omitHeaderOnOutput = false;
bool silentReceiver = false;
double txloss = 0.0;
double rxloss = 0.0;
bool loopback = false;
NormMsgr normMsgr;
@ -1003,6 +1007,15 @@ int main(int argc, char* argv[])
return -1;
}
}
else if (0 == strncmp(cmd, "rxloss", len))
{
if (1 != sscanf(argv[i++], "%lf", &rxloss))
{
fprintf(stderr, "nodeMsgr error: invalid 'rxloss' value!\n");
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "debug", len))
{
if (i >= argc)
@ -1073,6 +1086,7 @@ int main(int argc, char* argv[])
if (silentReceiver) normMsgr.SetSilentReceiver(true);
if (txloss > 0.0) normMsgr.SetTxLoss(txloss);
if (rxloss > 0.0) normMsgr.SetRxLoss(rxloss);
if (autoAck)
{

0
examples/normServer.cpp Normal file → Executable file
View File

39
examples/normSocket.cpp Normal file → Executable file
View File

@ -65,7 +65,7 @@ const char* NormNodeGetAddressString(NormNodeHandle node)
else
addrFamily = AF_INET6;
inet_ntop(addrFamily, addr, text, 31);
sprintf(text + strlen(text), "/%hu", port);
snprintf(text + strlen(text), 64 - strlen(text), "/%hu", port);
return text;
}
else
@ -521,9 +521,9 @@ bool NormSocket::Listen(UINT16 serverPort, const char* groupAddr, const char* se
// So that the listener can construct (unsent) ACKs without failure
NormSetDefaultUnicastNack(norm_session, true);
// Note we use a small buffer size here since a "listening" socket isn't
// Note we use a _small_ buffer size here since a "listening" socket isn't
// going to be receiving data (TBD - implement a mechanism to handoff remote
// sender (i.e. "client") from parent
// sender (i.e. "client") from parent directly?)
if (!NormStartReceiver(norm_session, 2048))
{
fprintf(stderr, "NormSocket::Listen() error: NormStartReceiver() failure (perhaps port already in use)\n");
@ -580,7 +580,7 @@ NormSocket* NormSocket::Accept(NormNodeHandle client, NormInstanceHandle instanc
// However, note that even though we've "connected" this sender,
// there is a chance that additional packets in the "serverSession"
// rx socket buffer may look like a new sender if deleted now, so
// we wait for NORM_REMOTE_SENDER_INACTIVE to delete
// we wait for NORM_REMOTE_SENDER_INACTIVE to delete the remote sender from the listener sesssion
#ifndef WIN32
// Enable rx port reuse since it's the server port, and connect
@ -1180,6 +1180,7 @@ void NormSocket::GetSocketEvent(const NormEvent& event, NormSocketEvent& socketE
socketEvent.type = NORM_SOCKET_CONNECT;
NormSetSynStatus(norm_session, false);
socket_state = CONNECTED;
// Since UDP connect/bind doesn't really work properly on
// Windows, the Windows NormSocket server farms out client connections
// to new ephemeral port numbers, so we need to update
@ -1187,12 +1188,11 @@ void NormSocket::GetSocketEvent(const NormEvent& event, NormSocketEvent& socketE
remote_node = event.sender;
UpdateRemoteAddress();
NormChangeDestination(norm_session, NULL, remote_port);
if (NORM_OBJECT_INVALID == tx_stream)
if ((NORM_OBJECT_INVALID == tx_stream) && !(IsMulticastClient() && IsServerSide()))
{
tx_stream = NormStreamOpen(norm_session, socket_option.buffer_size);
InitTxStream(tx_stream, socket_option.buffer_size, socket_option.segment_size, socket_option.num_data);
}
break;
case CONNECTED:
if (IsMulticastSocket())
@ -1200,7 +1200,31 @@ void NormSocket::GetSocketEvent(const NormEvent& event, NormSocketEvent& socketE
if (IsServerSocket())
{
// New client showing up at our multicast party
socketEvent.type = NORM_SOCKET_ACCEPT;
NormSocketInfo* socketInfo = client_table.FindSocketInfo(event.sender);
if (NULL == socketInfo)
{
// Add info for client socket pending acceptance
socketInfo = new NormSocketInfo(NormGetSocketInfo(event.sender));
if (NULL != socketInfo)
{
client_table.Insert(*socketInfo);
socketEvent.type = NORM_SOCKET_ACCEPT;
}
else
{
perror("NormSocket::GetSocketEvent() error: unable to add pending client info to server socket:\n");
}
}
else // duplicative accept event for existing socket, so ignore
{
ProtoAddress remoteAddr;
socketInfo->GetRemoteAddress(remoteAddr);
fprintf(stderr, "NormSocket::GetSocketEvent() warning: duplicative %s from client %s/%hu...\n",
(NORM_REMOTE_SENDER_NEW == event.type) ? "new" : "reset",
remoteAddr.GetHostString(), remoteAddr.GetPort());
// TBD - should we go ahead and delete this event.sender???
}
}
else
{
@ -1429,7 +1453,6 @@ void NormSocket::GetSocketEvent(const NormEvent& event, NormSocketEvent& socketE
else
{
// This still allows at least a chance of an ACK to be sent upon completion
TRACE("NormSetUserTimer(5) session: %p\n", norm_session);
NormSetUserTimer(norm_session, 0.0);
}
socketEvent.type = NORM_SOCKET_CLOSING;

42
examples/normSocket.h Normal file → Executable file
View File

@ -63,20 +63,20 @@ extern const double NORM_DEFAULT_CONNECT_TIMEOUT;
NormSocketHandle NormOpen(NormInstanceHandle instance);
bool NormListen(NormSocketHandle normSocket,
UINT16 serverPort,
bool NormListen(NormSocketHandle normSocket,
UINT16 serverPort,
const char* groupAddr = NULL,
const char* serverAddr = NULL);
const char* serverAddr = NULL);
bool NormConnect(NormSocketHandle normSocket,
const char* serverAddr,
UINT16 serverPort,
bool NormConnect(NormSocketHandle normSocket,
const char* serverAddr,
UINT16 serverPort,
UINT16 localPort = 0,
const char* groupAddr = NULL,
NormNodeId clientId = NORM_NODE_ANY);
NormSocketHandle NormAccept(NormSocketHandle serverSocket,
NormNodeHandle clientNode,
NormSocketHandle NormAccept(NormSocketHandle serverSocket,
NormNodeHandle clientNode,
NormInstanceHandle instance = NORM_INSTANCE_INVALID);
void NormReject(NormSocketHandle serverSocket,
@ -92,6 +92,30 @@ ssize_t NormWrite(NormSocketHandle normSocket, const void* buf, size_t nbyte);
int NormFlush(NormSocketHandle normSocket);
/*
// These calls _will_ be used for file/data object and message-stream delivery. (Sketching the calls out for now)
NormObject NormSendFile(NormSocketHandle normSocket,
const char* filePath,
const char* infoPtr,
ssize_t infoLen);
NormObject NormSendData(NormSocketHandle normSocket,
const char* data, // NormSocket will copy the "data" unlike NORM low-level API
ssize_t nbyte,
const char* infoPtr,
ssize_t infoLen);
// Notification events will indicate receipt of file/data objects. Are additional NormSocket API calls
// needed to manage receipt?
ssize_t NormSendMsg(NormSocketHandle normSocket, const char* data, ssize_t nbyte, bool flush);
ssize_t NormRecvMsg(NormSocketHandle normSocket, const char* data, ssize_t nbyte);
*/
// NormSocket helper functions
void NormSetSocketUserData(NormSocketHandle normSocket, const void* userData);
@ -119,7 +143,7 @@ typedef enum NormSocketEventType
} NormSocketEventType;
// Right now, these options MUST be set after NormOpen()
// Right now, these options MUST be set _after_ NormOpen()
// but _before_ NormConnect() or NormListen()
// (This will be expanded, perhaps to include parameters
// that can be changed after connection setup)

0
examples/normSocketNotes.txt Normal file → Executable file
View File

0
examples/normStreamRecv.cpp Normal file → Executable file
View File

0
examples/normStreamSend.cpp Normal file → Executable file
View File

65
examples/normStreamer.cpp Normal file → Executable file
View File

@ -17,7 +17,7 @@
#include <sys/timerfd.h>
#endif // LINUX
const unsigned int LOOP_MAX = 100;
const unsigned int LOOP_MAX = 1;
// Setting SHOOT_FIRST to non-zero means that an ACK request
// will be used to advance the acking "watermark" point
@ -70,7 +70,10 @@ class NormStreamer
{
loopback = state;
if (NORM_SESSION_INVALID != norm_session)
{
NormSetMulticastLoopback(norm_session, state);
NormSetLoopback(norm_session, state); // XXX test code
}
}
void SetFtiInfo(bool state)
{
@ -256,6 +259,8 @@ class NormStreamer
{NormSetSilentReceiver(norm_session, state);}
void SetTxLoss(double txloss)
{NormSetTxLoss(norm_session, txloss);}
void SetRxLoss(double rxloss)
{NormSetRxLoss(norm_session, rxloss);}
// Set the scheduler for running the app and norm threads.
static bool BoostPriority();
@ -565,11 +570,14 @@ bool NormStreamer::OpenNormSession(NormInstanceHandle instance, const char* addr
{
NormSetRxPortReuse(norm_session, true);
if (loopback)
{
NormSetMulticastLoopback(norm_session, true);
}
}
NormSetLoopback(norm_session, loopback);
// Set some default parameters (maybe we should put parameter setting in Start())
NormSetDefaultSyncPolicy(norm_session, NORM_SYNC_STREAM);
NormSetDefaultSyncPolicy(norm_session, NORM_SYNC_CURRENT);
if (!is_multicast)
NormSetDefaultUnicastNack(norm_session, true);
@ -703,7 +711,7 @@ bool NormStreamer::Start(bool sender, bool receiver)
void NormStreamer::ReadInputSocket()
{
unsigned int loopCount = 0;
NormSuspendInstance(NormGetInstance(norm_session));
//NormSuspendInstance(NormGetInstance(norm_session));
while (input_needed && input_ready && (loopCount < LOOP_MAX))
{
loopCount++;
@ -731,7 +739,7 @@ void NormStreamer::ReadInputSocket()
input_ready = false;
}
}
NormResumeInstance(NormGetInstance(norm_session));
//NormResumeInstance(NormGetInstance(norm_session));
} // end NormStreamer::ReadInputSocket()
void NormStreamer::ReadInput()
@ -740,7 +748,7 @@ void NormStreamer::ReadInput()
// The loop count makes sure we don't spend too much time here
// before going back to the main loop to handle NORM events, etc
unsigned int loopCount = 0;
NormSuspendInstance(NormGetInstance(norm_session));
//NormSuspendInstance(NormGetInstance(norm_session));
while (input_needed && input_ready && (loopCount < LOOP_MAX))
{
loopCount++;
@ -758,7 +766,9 @@ void NormStreamer::ReadInput()
assert(input_index < input_msg_length);
numBytes = input_msg_length - input_index;
}
//TRACE("reading STDIN ...\n");
ssize_t result = read(input_fd, input_buffer + input_index, numBytes);
//TRACE(" result: %d\n", (int)result);
if (result > 0)
{
input_index += result;
@ -825,7 +835,7 @@ void NormStreamer::ReadInput()
break;
}
} // end while (input_needed && input_ready)
NormResumeInstance(NormGetInstance(norm_session));
//NormResumeInstance(NormGetInstance(norm_session));
} // end NormStreamer::ReadInput()
void NormStreamer::SendData()
@ -887,11 +897,11 @@ unsigned int NormStreamer::WriteToStream(const char* buffer, unsigned int numByt
if (ack_ex)
{
const char* req = "Hello, acker";
NormSetWatermarkEx(norm_session, tx_stream, req, strlen(req) + 1);
NormSetWatermarkEx(norm_session, tx_stream, req, strlen(req) + 1);//, true);
}
else
{
NormSetWatermark(norm_session, tx_stream);
NormSetWatermark(norm_session, tx_stream);//, true);
}
tx_watermark_pending = true;
@ -992,7 +1002,7 @@ void NormStreamer::RecvData()
// before going back to the main loop to handle NORM events, etc
unsigned int loopCount = 0;
// Reads data from rx_stream to available output_buffer
NormSuspendInstance(NormGetInstance(norm_session));
//NormSuspendInstance(NormGetInstance(norm_session));
while (rx_needed && rx_ready && (loopCount < LOOP_MAX))
{
loopCount++;
@ -1057,7 +1067,7 @@ void NormStreamer::RecvData()
WriteOutput();
}
}
NormResumeInstance(NormGetInstance(norm_session));
//NormResumeInstance(NormGetInstance(norm_session));
} // end NormStreamer::RecvData()
@ -1112,8 +1122,8 @@ void NormStreamer::WriteOutput()
if (0 != output_bucket_depth)
{
// Debit output token bucket since it's active
if (result > output_bucket_count)
TRACE("result:%d output_bucket_count:%u\n", (int)result, output_bucket_count);
//if (result > output_bucket_count)
// TRACE("result:%d output_bucket_count:%u\n", (int)result, output_bucket_count);
ASSERT(output_bucket_count >= result);
output_bucket_count -= result;
}
@ -1166,7 +1176,7 @@ void NormStreamer::HandleNormEvent(const NormEvent& event)
break;
case NORM_GRTT_UPDATED:
//fprintf(stderr, "new GRTT = %lf\n", NormGetGrttEstimate(norm_session));
//TRACE("normStreamer: new GRTT = %lf\n", NormGetGrttEstimate(norm_session));
break;
case NORM_ACKING_NODE_NEW:
@ -1176,7 +1186,6 @@ void NormStreamer::HandleNormEvent(const NormEvent& event)
break;
case NORM_TX_WATERMARK_COMPLETED:
TRACE("NORM_TX_WATERMARK_COMPLETED ...\n");
if (NORM_ACK_SUCCESS == NormGetAckingStatus(norm_session))
{
//fprintf(stderr, "WATERMARK COMPLETED\n");
@ -1353,8 +1362,8 @@ void Usage()
" [insockbuffer <bytes>] [outsockbuffer <bytes>]\n"
" [txsockbuffer <bytes>] [rxsockbuffer <bytes>]\n"
" [streambuffer <bytes>]\n"
" [check64 | check32]\n"
" [omit] [silent] [txloss <lossFraction>]\n");
" [check64 | check32] [omit] [silent]\n"
" [txloss <lossFraction>] [rxloss <lossFraction>]\n");
} // end Usage()
void PrintHelp()
@ -1437,6 +1446,7 @@ int main(int argc, char* argv[])
bool omitHeaderOnOutput = false;
bool silentReceiver = false;
double txloss = 0.0;
double rxloss = 0.0;
bool boostPriority = false;
unsigned int checkSequence = 0; // can set to 64 or 32
// TBD - set these defaults to reasonable values or just use NormStreamer constructor defaults
@ -1445,7 +1455,7 @@ int main(int argc, char* argv[])
unsigned long outputSocketBufferSize = 0; // 6*1024*1024;
unsigned long txSocketBufferSize = 0; // 6*1024*1024;
unsigned long rxSocketBufferSize = 0; // 6*1024*1024;
unsigned long streamBufferSize = 1*1024*1024;
unsigned long streamBufferSize = 2*1024*1024;
// Instantiate a NormStreamer and set default params
NormStreamer normStreamer;
@ -1955,6 +1965,15 @@ int main(int argc, char* argv[])
return -1;
}
}
else if (0 == strncmp(cmd, "rxloss", len))
{
if (1 != sscanf(argv[i++], "%lf", &rxloss))
{
fprintf(stderr, "normStreamer error: invalid 'rxloss' value!\n");
Usage();
return -1;
}
}
else if (0 == strncmp(cmd, "debug", len))
{
if (i >= argc)
@ -2040,6 +2059,7 @@ int main(int argc, char* argv[])
// TBD - should provide more error checking of NORM API calls
NormInstanceHandle normInstance = NormCreateInstance(boostPriority);
NormSetDebugLevel(debugLevel);
if ((NULL != logFile) && !NormOpenDebugLog(normInstance, logFile))
{
@ -2069,6 +2089,7 @@ int main(int argc, char* argv[])
if (silentReceiver) normStreamer.SetSilentReceiver(true);
if (txloss > 0.0) normStreamer.SetTxLoss(txloss);
if (rxloss > 0.0) normStreamer.SetRxLoss(rxloss);
for (unsigned int i = 0; i < ackingNodeCount; i++)
normStreamer.AddAckingNode(ackingNodeList[i]);
@ -2117,6 +2138,7 @@ int main(int argc, char* argv[])
int maxfd = -1;
int fdMask = 0;
bool waitOnNorm = false;
bool waitOnInput = false;
double timeoutInterval = -1.0;
if (send)
{
@ -2132,6 +2154,7 @@ int main(int argc, char* argv[])
FD_SET(inputfd, &fdsetInput);
if (inputfd > maxfd) maxfd = inputfd;
fdMask |= 0x01;
waitOnInput = true;
}
}
else
@ -2249,6 +2272,7 @@ int main(int argc, char* argv[])
timeout.tv_sec = timeout.tv_usec = 0;
}
#endif // if/else LINUX
//ßTRACE("waitOnNorm:%d waitOnInput:%d\n", waitOnNorm, waitOnInput);
int result = select(maxfd+1, &fdsetInput, &fdsetOutput, NULL, timeoutPtr);
switch (result)
{
@ -2285,9 +2309,14 @@ int main(int argc, char* argv[])
}
// We always clear out/handle pending NORM API events
// (to keep event queue from building up)
unsigned int eventCount = 0;
const unsigned int maxBurstCount = 50;
NormEvent event;
while (NormGetNextEvent(normInstance, &event, false))
while ((eventCount < maxBurstCount) && (NormGetNextEvent(normInstance, &event, false)))
{
normStreamer.HandleNormEvent(event);
eventCount += 1;
}
struct timeval thisTime;
gettimeofday(&thisTime, NULL);

View File

@ -29,7 +29,7 @@ def main(argv):
(opts, args) = get_option_parser().parse_args(argv)
if len(args) != 1:
print USAGE
print(USAGE)
return 1
pipep = PipeParser(opts.pipe)
@ -53,7 +53,7 @@ def main(argv):
except IndexError:
continue
pipep.reports.task_done()
print "Exiting..."
print("Exiting...")
# g.reset()
# g.close()
# del g

425
examples/python/normCast.py Normal file
View File

@ -0,0 +1,425 @@
'''
LD_LIBRARY_PATH=/home/honglei/norm_test/
'''
# sender/Win10:
#--id 34252 --send "C:\Users\Admin\AppData\Roaming\Wing Pro 9" --repeat 1 --addr 224.1.2.4/6003 --txaddr 10.65.39.191/8002 --cc rate 5000 --ack auto --grttprobing active --debug 4
# receiver/Debian10
#--id 172042016 --recv "~/recvFiles" --addr 224.1.2.4/6003 --interface ens33 --unicast_nack --debug 4
import sys
import os
if os.name =='nt':
os.add_dll_directory(os.path.dirname(__file__))
import argparse
import traceback
import logging
from typing import Optional
import enum
class CCEnum(enum.Enum):
CC = "cc"
CCE = "cce"
CCL = "ccl"
Fixed = "rate"
class FlushEnum(enum.Enum):
none='none'
passive='passive'
active='active'
class GrttEnum(enum.Enum):
none='none'
passive='passive'
active='active'
class EnumAction(argparse.Action):
"""
Argparse action for handling Enums
from https://stackoverflow.com/questions/43968006/support-for-enum-arguments-in-argparse
"""
def __init__(self, **kwargs):
# Pop off the type value
enum_type = kwargs.pop("type", None)
# Ensure an Enum subclass is provided
if enum_type is None:
raise ValueError("type must be assigned an Enum when using EnumAction")
if not issubclass(enum_type, enum.Enum):
raise TypeError("type must be an Enum when using EnumAction")
# Generate choices from the Enum
#kwargs.setdefault("choices", tuple(e.value for e in enum_type)) #if e!=CCEnum.rate else "rate <bitsPerSecond>"
super(EnumAction, self).__init__(**kwargs)
self._enum = enum_type
def __call__(self, parser, namespace, values:list|str, option_string=None):
# Convert value back into an Enum
if isinstance(values,list):
if len(values) ==2:
value = int(values[1])
elif len(values) ==1:
value = self._enum( values[0].lower())
else:
value = self._enum(values.lower() )
setattr(namespace, self.dest, value)
'''
norm.cpp:
fprintf(stderr, "Usage: normCast {send <file/dir list> &| recv <rxCacheDir>} [silent {on|off}]\n"
" [repeat <interval> [updatesOnly]] [id <nodeIdInteger>]\n"
" [addr <addr>[/<port>]][txaddr <addr>[/<port>]][txport <port>]\n"
" [interface <name>][reuse][loopback]\n"
" [ack auto|<node1>[,<node2>,...]] [segment <bytes>]\n"
" [block <count>] [parity <count>] [auto <count>]\n"
" [cc|cce|ccl|rate <bitsPerSecond>] [rxloss <lossFraction>]\n"
" [txloss <lossFraction>] [flush {none|passive|active}]\n"
" [grttprobing {none|passive|active}] [grtt <secs>]\n"
" [ptos <value>] [processor <processorCmdLine>] [saveaborts]\n"
" [sentprocessor <processorCmdLine>]\n"
" [purgeprocessor <processorCmdLine>] [buffer <bytes>]\n"
" [txsockbuffer <bytes>] [rxsockbuffer <bytes>]\n"
" [debug <level>] [trace] [log <logfile>]\n");
'''
# Instantiate the parser
def get_arg_options():
parser = argparse.ArgumentParser(description='Optional app description')
## Required positional argument
parser.add_argument('--id', type=int, required=True,
help='id <nodeIdInteger>')
parser.add_argument('--send', '-S',nargs='+',
help='send <file/dir list>')
parser.add_argument('--recv', '-R',
help='recv <rxCacheDir>')
parser.add_argument('--repeat','-r', type=int, default=60,
help='[repeat <interval> [updatesOnly]]')
parser.add_argument('--interface', '-i',
help='addr <addr>[/<port>]')
parser.add_argument('--addr', '-a',
help='addr <addr>[/<port>]')
parser.add_argument('--txaddr', '-t',
help='txaddr <addr>[/<port>]')
parser.add_argument('--txport', type=int,
help='txport <port>')
parser.add_argument('--ack', nargs='+', #nargs='?',
help='ack auto|<node1>[,<node2>,...')
#To create an option that needs no value, set the action [docs] of it to 'store_const', 'store_true' or 'store_false'
parser.add_argument('--loopback', action='store_true',help='')
parser.add_argument('--segment', type=int,
help='segment <bytes>')
parser.add_argument('--block', type=int,
help='[block <count>] ')
parser.add_argument('--parity', type=int,
help='[parity <count>]')
parser.add_argument('--auto', type=int,
help='[auto <count>]')
parser.add_argument('--grttprobing', type=GrttEnum, action=EnumAction,
help='[grttprobing {none|passive|active}]')
parser.add_argument('--grtt', type=int, help='[grtt <secs>]')
parser.add_argument('--ptos', type=int,
help='[ptos <value>]')
parser.add_argument('--flush', type=FlushEnum, action=EnumAction,
help='[flush {none|passive|active}]')
parser.add_argument('--silent', action='store_true',help='')
parser.add_argument('--unicast_nack', action='store_true', help='')
parser.add_argument('--txloss', type=float, help='[txloss <lossFraction>]')
parser.add_argument('--rxloss', type=float, help='[rxloss <lossFraction>]')
parser.add_argument('--buffer', type=int, help='[buffer <bytes>]')
parser.add_argument('--txsockbuffer', type=int, help=' [txsockbuffer <bytes>]')
parser.add_argument('--rxsockbuffer', type=int, help='[rxsockbuffer <bytes>]')
parser.add_argument('--debug', type=int, help='[debug <level>]')
parser.add_argument('--cc',type=CCEnum, nargs='+', action=EnumAction,
help='[cc|cce|ccl|rate <bitsPerSecond>] '
)
args = parser.parse_args()
return args
import pynorm
def create_session(instance:pynorm.Instance, opts:argparse.Namespace):
'''
use opts to create a NORM session
'''
sessionAddr ='224.1.2.3'
sessionPort = 6003
if opts.addr:
args = opts.addr.split('/')
if len(args) >0:
sessionAddr = args[0]
if len(args) ==2:
sessionPort = int(args[1])
session = instance.createSession(sessionAddr, sessionPort, localId=opts.id)
sessionTxAddr:str = None
sessionTxPort = 8002
if opts.txaddr:
args = opts.txaddr.split('/')
if len(args) >0:
sessionTxAddr = args[0]
if len(args) ==2:
sessionTxPort = int(args[1])
if sessionTxAddr:
session.setTxPort(txPort=sessionTxPort, txBindAddr=sessionTxAddr)
if opts.interface:
session.setMulticastInterface(opts.interface)
if opts.loopback:
session.setLoopback(loopbackEnable=True)
if opts.silent:
session.setSilentReceiver(True)
if opts.unicast_nack:
session.setDefaultUnicastNack(enable=True)
autoAck:bool = False
ackingNodeList:list[int] =[]
if opts.ack:
if 'auto' == opts.ack[0]:
autoAck = True
session.setAutoAckingNodes(pynorm.TrackingStatus.RECEIVERS)
else:
ackingNodeList = [ int(i) for i in opts.ack]
for ackingNondeID in ackingNodeList:
session.addAckingNode(ackingNondeID)
if opts.txloss and opts.txloss>0:
session.setTxLoss(opts.txloss)
if opts.rxloss and opts.rxloss>0:
session.setRxLoss(opts.rxloss)
# Congestion Control
if opts.cc:
if isinstance(opts.cc,int):
session.setTxRate(opts.cc)
session.setEcnSupport(ecnEnable=False)
else:
if opts.cc == CCEnum.CC: # default TCP-friendly congestion control
session.setEcnSupport(ecnEnable=False)
elif opts.cc == CCEnum.CCE: #"wireless-ready" ECN-only congestion control
session.setEcnSupport(ecnEnable=True, ignoreLoss=True)
elif opts.cc == CCEnum.CCL: # "loss tolerant", non-ECN congestion control
session.setEcnSupport(ecnEnable=False, ignoreLoss=False, tolerateLoss=True)
defaultBufferSpace = 64*1024*1024
defaultTxSocketBufferSize = 4*1024*1024
defaultRxSocketBufferSize = 6*1024*1024
bufferSpace = opts.buffer if opts.buffer else defaultBufferSpace
if opts.send:
if opts.ack:
session.setFlowControl(flowControlFactor=0) #// ack-based flow control enabled on command-line, so disable timer-based flow control
session.setBackoffFactor(0)
#FEC
session.startSender(sessionId=opts.id,
bufferSpace=bufferSpace,
segmentSize=opts.segment if opts.segment else 1400,
blockSize=opts.block if opts.block else 64,
numParity=opts.parity if opts.parity else 0,
fecId=0)
if opts.auto:
session.setAutoParity(opts.auto)
session.setTxSocketBuffer(opts.txsockbuffer if opts.txsockbuffer else defaultTxSocketBufferSize )
if opts.recv:
session.startReceiver(bufferSpace=bufferSpace)
session.setRxSocketBuffer(opts.rxsockbuffer if opts.rxsockbuffer else defaultRxSocketBufferSize )
if opts.grttprobing:
session.setGrttProbingMode(pynorm.ProbingMode[ opts.grttprobing.value.upper() ] )
return session
from pynorm import EventType
from typing import Iterable
def listFiles( dirFileList:list[str]) -> Iterable[str]:
for dirFile in dirFileList:
if os.path.isfile(dirFile):
yield dirFile
elif os.path.isdir(dirFile):
for filename in os.scandir(dirFile):
if filename.is_file():
yield filename.path
else:
raise FileExistsError(f"{dirFile} is not a valid file/dir")
import logging
import ipaddress
class NormCaster():
def __init__(self,instance:pynorm.Instance, opts:argparse.Namespace ):
self.opts:argparse.Namespace = opts
self.recvDir:Optional[str] = os.path.expanduser(opts.recv) if opts.recv else None
self.instance:pynorm.Instance = instance
self.session:pynorm.Session = create_session(instance, opts)
self.fileIterator:Iterable[str] = listFiles(opts.send)
self.is_running:bool = True
self.pendingSendFilePath:Optional[str] = None #
def addOneFile(self,session):
'''
'''
if self.pendingSendFilePath is None:
try:
self.pendingSendFilePath:str = self.fileIterator.__next__()
except StopIteration:
self.is_running = False
return
lastSlash = self.pendingSendFilePath.rfind('/')
filename = self.pendingSendFilePath[lastSlash+1:]
obj:Optional[pynorm.Object] = session.fileEnqueue(self.pendingSendFilePath, info= filename.encode() )
if obj:
if self.opts.ack:
session.setWatermark(obj,True)
logging.info(f"add file:{self.pendingSendFilePath} {obj._object}")
self.pendingSendFilePath = None # succeed enqued
else:
logging.warning(f"fileEnqueue: {self.pendingSendFilePath} failure!")
def handle_norm_event(self, event:pynorm.Event):
session:pynorm.Session = event.session
evtType:pynorm.EventType = event.type
logging.info(evtType )
if evtType in (EventType.TX_QUEUE_EMPTY, EventType.TX_QUEUE_VACANCY):
self.addOneFile(session)
elif evtType == EventType.GRTT_UPDATED:
pass
elif evtType == EventType.TX_WATERMARK_COMPLETED:
if pynorm.AckingStatus.SUCCESS == session.getAckingStatus():
logging.warning( "normCast: NORM_TX_WATERMARK_COMPLETED, NORM_ACK_SUCCESS");
self.addOneFile(session)
else:
logging.warning( "normCast: NORM_TX_WATERMARK_COMPLETED, _NOT_ NORM_ACK_SUCCESS");
obj = event.object
if obj is None:
session.resetWatermark()
elif evtType == EventType.TX_FLUSH_COMPLETED:
pass
elif evtType == EventType.TX_OBJECT_PURGED:
obj = event.object
if obj and obj.type== pynorm.ObjectType.FILE:
logging.info(f"normCast: send file purged: {obj.info.decode()}")
elif evtType == EventType.TX_OBJECT_SENT:
obj = event.object
if obj and obj.type== pynorm.ObjectType.FILE:
logging.info(f"initial send complete: {obj.info.decode()}")
self.addOneFile(session)
elif evtType == EventType.ACKING_NODE_NEW:
sender = event.sender
logging.info(f"normCast: new acking node: {sender.id} IP address{sender.address}")
elif evtType == EventType.REMOTE_SENDER_INACTIVE:
pass
elif evtType == EventType.RX_OBJECT_ABORTED:
obj = event.object
if obj and obj.type is not pynorm.ObjectType.FILE:
logging.error("normCast: received invalid object type?!")
return
filePath = event.object.filename
event.object.cancel()
#remove temparary file if recv aborted.
os.remove(filePath)
logging.info("")
elif evtType == EventType.RX_OBJECT_INFO:
pass
elif evtType == EventType.RX_OBJECT_COMPLETED:
obj = event.object
if obj and obj.type is not pynorm.ObjectType.FILE:
logging.error("normCast: received invalid object type?!")
return
file_path = event.object.info.decode()
fileName = os.path.split(file_path)[-1]
path = os.path.join( self.recvDir, fileName )
oldPath = event.object.filename
logging.debug (f"{oldPath=}")
try:
if os.path.isfile(path):
os.remove(path)
os.rename(src=oldPath, dst=path)
except Exception as e:
logging.error ( traceback.format_exc() )
def getAckNodesStatus(self,session):
isSuccess, nodeID, nodeAckStatus = session.getNextAckingNode()
while isSuccess:
ip=ipaddress.IPv4Address(nodeID)
if pynorm.AckingStatus.SUCCESS == nodeAckStatus:
logging.info( f"normCast: node {nodeID} (IP address: {str(ip)}) acnkowledged.")
else:
logging.info( f"normCast: node {nodeID} (IP address: {str(ip)}) failed to acnkowledge.")
isSuccess, nodeID, nodeAckStatus = session.getNextAckingNode()
def run(self):
while self.is_running:
event: Optional[pynorm.Event,bool,None] = self.instance.getNextEvent(timeout=self.opts.repeat)
while event:
self.handle_norm_event(event)
event = self.instance.getNextEvent(timeout=self.opts.repeat)
if event is None and self.opts.send:
self.addOneFile(self.session) # means timeout
logging.warning("normCast exits!")
def main(argv):
opts:argparse.Namespace = get_arg_options()
instance = pynorm.Instance()
if opts.debug:
instance.setDebugLevel(level=pynorm.DebugLevel(opts.debug) )
if opts.recv:
recvPath:str = os.path.expanduser( opts.recv )
if not os.path.isdir(recvPath): #create is not exists!
os.makedirs( recvPath )
instance.setCacheDirectory( recvPath )
normCast:NormCaster = NormCaster(instance, opts)
if opts.send:
normCast.addOneFile(normCast.session)
normCast.run()
if __name__ == '__main__':
logging.getLogger().setLevel(logging.INFO)
sys.exit(main(sys.argv))

View File

@ -28,7 +28,7 @@ def main(argv):
(opts, args) = get_option_parser().parse_args(argv)
if len(args) != 2:
print get_option_parser().get_usage()
print(get_option_parser().get_usage())
return 1
path = os.path.abspath(args[1])
@ -45,26 +45,26 @@ def main(argv):
for event in instance:
if event == 'NORM_RX_OBJECT_INFO':
event.object.filename = os.path.join(path, event.object.info)
print 'Downloading file %s' % event.object.filename
print('Downloading file %s' % event.object.filename)
elif event == 'NORM_RX_OBJECT_UPDATED':
print 'File %s - %i bytes left to download' % (
event.object.filename, event.object.bytesPending)
print('File %s - %i bytes left to download' % (
event.object.filename, event.object.bytesPending))
elif event == 'NORM_RX_OBJECT_COMPLETED':
print 'File %s completed' % event.object.filename
print('File %s completed' % event.object.filename)
return 0
elif event == 'NORM_RX_OBJECT_ABORTED':
print 'File %s aborted' % event.object.filename
print('File %s aborted' % event.object.filename)
return 1
else:
print event
print(event)
except KeyboardInterrupt:
pass
print 'Exiting.'
print('Exiting.')
return 0
if __name__ == '__main__':

View File

@ -10,7 +10,7 @@ from random import randint
import pynorm
USAGE = 'usage: %s [options] <file>' % sys.argv[0]
DEFAULT_ADDR = '224.1.2.3'
DEFAULT_ADDR = u'224.1.2.3'
DEFAULT_PORT = 6003
def get_option_parser():
@ -29,7 +29,7 @@ def main(argv):
(opts, args) = get_option_parser().parse_args(argv)
if len(args) != 2:
print get_option_parser().get_usage()
print(get_option_parser().get_usage())
return 1
filepath = os.path.abspath(args[1])
@ -40,23 +40,23 @@ def main(argv):
session = instance.createSession(opts.address, opts.port)
if opts.iface:
session.setMulticastInterface(opts.iface)
session.setTxRate(256e10)
session.setTxRate(1.0e+06)
session.startSender(randint(0, 1000), 1024**2, 1400, 64, 16)
print 'Sending file %s' % filename
session.fileEnqueue(filepath, filename)
print(('Sending file %s' % filename))
session.fileEnqueue(filepath, info=filename.encode())
try:
for event in instance:
if event == 'NORM_TX_FLUSH_COMPLETED':
print 'Flush completed, exiting.'
print(event)
if str(event) == 'NORM_TX_FLUSH_COMPLETED':
print('Flush completed, exiting.')
return 0
else:
print event
except KeyboardInterrupt:
pass
print 'Exiting.'
print('Exiting.')
return 0
# end main

46
examples/python/normMsgr.py Normal file → Executable file
View File

@ -14,19 +14,19 @@ class InputThread(Thread):
def __init__(self, parent, *args, **kwargs):
super(InputThread, self).__init__(*args, **kwargs)
self.setDaemon(True) ;# this is "child" daemon thread
self.daemon = True
self.msgr = parent
def run(self):
while True:
try:
msgHdr = bytearray(sys.stdin.read(MSG_HDR_SIZE))
msgHdr = sys.stdin.buffer.read(MSG_HDR_SIZE)
except:
sys.stderr.write("normMsgr: input thread end-of-file 1 ...\n")
return
try:
msgSize = 256*int(msgHdr[0]) + int(msgHdr[1])
msgBuffer = sys.stdin.read(msgSize - 2)
msgBuffer = sys.stdin.buffer.read(msgSize - 2)
except:
sys.stderr.write("normMsgr: input thread end-of-file 2 ...\n")
return
@ -37,7 +37,7 @@ class OutputThread(Thread):
def __init__(self, parent, *args, **kwargs):
super(OutputThread, self).__init__(*args, **kwargs)
self.setDaemon(True) ;# this is "child" daemon thread
self.daemon = True
self.msgr = parent
def run(self):
@ -47,11 +47,15 @@ class OutputThread(Thread):
msgHeader = bytearray(MSG_HDR_SIZE)
msgHeader[0] = (msgLen >> 8) & 0x00ff
msgHeader[1] = msgLen & 0x00ff
sys.stdout.write(msgHeader)
sys.stdout.write(msg)
try:
sys.stdout.buffer.write(msgHeader)
sys.stdout.buffer.write(msg)
sys.stdout.flush()
except:
sys.stderr.write("normMsgr: output thread exiting ...\n")
return
del msg
class NormMsgr:
"""This class keeps state for NORM tx/rx operations"""
@ -78,10 +82,12 @@ class NormMsgr:
# Create a NormSession and set some default parameters
self.normSession = self.normInstance.createSession(addr, port, nodeId)
self.normSession.setRxCacheLimit(2*self.norm_tx_queue_max) ;# we let the receiver track some extra objects
self.normSession.setDefaultSyncPolicy(pynorm.NORM_SYNC_ALL);
self.normSession.setDefaultSyncPolicy(pynorm.SyncPolicy.ALL);
self.normSession.setDefaultUnicastNack(True);
self.normSession.setTxCacheBounds(10*1024*1024, self.norm_tx_queue_max, self.norm_tx_queue_max);
self.normSession.setCongestionControl(True, True);
self.normSession.setRxPortReuse(True)
self.normSession.setMulticastLoopback(True)
return self.normSession
def addAckingNode(self, nodeId):
@ -203,7 +209,7 @@ class NormMsgr:
def onNormRxObjectCompleted(self, obj):
with self.normRxLock:
if pynorm.NORM_OBJECT_DATA == obj.getType():
if pynorm.ObjectType.DATA == obj.getType():
if 0 != len(self.output_msg_queue):
wasEmpty = False
else:
@ -233,7 +239,8 @@ class NormEventHandler(Thread):
def __init__(self, parentMsgr, *args, **kwargs):
super(NormEventHandler, self).__init__(*args, **kwargs)
self.setDaemon(True) ;# this is "child" daemon thread
#self.setDaemon(True) ;# this is "child" daemon thread (setDaemon is deprecated)
self.daemon = True
self.lock = Lock()
self.msgr = parentMsgr
@ -248,12 +255,12 @@ class NormEventHandler(Thread):
return
if event is None:
break
if pynorm.NORM_EVENT_INVALID == event.type:
if pynorm.EventType.EVENT_INVALID == event.type:
continue
elif pynorm.NORM_TX_QUEUE_EMPTY == event.type or pynorm.NORM_TX_QUEUE_VACANCY == event.type:
elif pynorm.EventType.TX_QUEUE_EMPTY == event.type or pynorm.EventType.TX_QUEUE_VACANCY == event.type:
msgr.onNormTxQueueVacancy()
elif pynorm.NORM_TX_WATERMARK_COMPLETED == event.type:
if pynorm.NORM_ACK_SUCCESS == event.session.getAckingStatus():
elif pynorm.EventType.TX_WATERMARK_COMPLETED == event.type:
if pynorm.EventType.ACK_SUCCESS == event.session.getAckingStatus():
# All receivers acknowledged
msgr.onNormTxWatermarkCompleted()
else:
@ -261,12 +268,12 @@ class NormEventHandler(Thread):
# from our acking list. For now, we are infinitely
# persistent by resetting watermark ack request
event.session.resetWatermark()
elif pynorm.NORM_TX_OBJECT_PURGED == event.type:
elif pynorm.EventType.TX_OBJECT_PURGED == event.type:
msgr.onNormTxObjectPurged(event.object)
elif pynorm.NORM_RX_OBJECT_COMPLETED == event.type:
elif pynorm.EventType.RX_OBJECT_COMPLETED == event.type:
msgr.onNormRxObjectCompleted(event.object)
#else:
# sys.stderr.write("normMsgr: NormEventHandler warning: unhandled event: %s\n" % str(event))
#sys.stderr.write("normMsgr: NormEventHandler warning: unhandled event: %s\n" % pynorm.EventType(event.type))
sys.stderr.write("normMsgr: NormEventHandler thread exiting ...\n");
self.lock.release()
@ -393,4 +400,9 @@ except KeyboardInterrupt:
#sys.stderr.write("exception while waiting on input thread ..\n");
pass
# TBD - shut the NormEventHandler thread down in a graceful way
if send:
inputThread.join()
if recv:
outputThread.join()
sys.stderr.write("normMsgr: Done.\n")

0
examples/win32InputHandler.cpp Normal file → Executable file
View File

0
examples/wintest.cpp Normal file → Executable file
View File

0
include/galois.h Normal file → Executable file
View File

329
include/normApi.h Normal file → Executable file
View File

@ -52,10 +52,10 @@ typedef uint32_t UINT32;
// is removed, the API shouldn't be considered final.
#ifndef __cplusplus
# include <stdbool.h>
# define DEFAULT(arg)
#include <stdbool.h>
#define DEFAULT(arg)
#else
# define DEFAULT(arg) = arg
#define DEFAULT(arg) = arg
#endif
#ifdef __cplusplus
@ -64,7 +64,7 @@ extern "C" {
#define NORM_VERSION_MAJOR 1
#define NORM_VERSION_MINOR 5
#define NORM_VERSION_PATCH 7
#define NORM_VERSION_PATCH 10
/** NORM API Types */
typedef const void* NormInstanceHandle;
@ -77,7 +77,7 @@ const NormSessionHandle NORM_SESSION_INVALID;
typedef UINT16 NormSessionId;
typedef const void* NormNodeHandle;
extern NORM_API_LINKAGE
extern NORM_API_LINKAGE
const NormNodeHandle NORM_NODE_INVALID;
typedef UINT32 NormNodeId;
extern NORM_API_LINKAGE
@ -96,74 +96,65 @@ typedef __int64 NormSize;
typedef off_t NormSize;
#endif // WIN32
NORM_API_LINKAGE
typedef enum NormObjectType
{
NORM_OBJECT_NONE,
NORM_OBJECT_DATA,
NORM_OBJECT_FILE,
NORM_OBJECT_STREAM
} NormObjectType;
NORM_API_LINKAGE
NORM_OBJECT_STREAM
} NORM_API_LINKAGE NormObjectType;
typedef enum NormFlushMode
{
NORM_FLUSH_NONE,
NORM_FLUSH_PASSIVE,
NORM_FLUSH_ACTIVE
} NormFlushMode;
NORM_API_LINKAGE
NORM_FLUSH_ACTIVE
} NORM_API_LINKAGE NormFlushMode;
typedef enum NormNackingMode
{
NORM_NACK_NONE,
NORM_NACK_INFO_ONLY,
NORM_NACK_NORMAL
} NormNackingMode;
NORM_NACK_NORMAL
} NORM_API_LINKAGE NormNackingMode;
NORM_API_LINKAGE
typedef enum NormAckingStatus
{
NORM_ACK_INVALID,
NORM_ACK_FAILURE,
NORM_ACK_PENDING,
NORM_ACK_SUCCESS
} NormAckingStatus;
NORM_API_LINKAGE
NORM_ACK_SUCCESS
} NORM_API_LINKAGE NormAckingStatus;
typedef enum NormTrackingStatus
{
NORM_TRACK_NONE,
NORM_TRACK_RECEIVERS,
NORM_TRACK_SENDERS,
NORM_TRACK_ALL
} NormTrackingStatus;
NORM_TRACK_ALL
} NORM_API_LINKAGE NormTrackingStatus;
NORM_API_LINKAGE
typedef enum NormProbingMode
{
NORM_PROBE_NONE,
NORM_PROBE_PASSIVE,
NORM_PROBE_ACTIVE
} NormProbingMode;
NORM_API_LINKAGE
NORM_PROBE_ACTIVE
} NORM_API_LINKAGE NormProbingMode;
typedef enum NormSyncPolicy
{
NORM_SYNC_CURRENT, // attempt to receiver current/new objects only, join mid-stream
NORM_SYNC_STREAM, // sync to current stream, but to beginning of stream
NORM_SYNC_ALL // attempt to receive old and new objects
} NormSyncPolicy;
NORM_API_LINKAGE
} NORM_API_LINKAGE NormSyncPolicy;
typedef enum NormRepairBoundary
{
NORM_BOUNDARY_BLOCK,
NORM_BOUNDARY_OBJECT
} NormRepairBoundary;
NORM_API_LINKAGE
} NORM_API_LINKAGE NormRepairBoundary;
typedef enum NormEventType
{
NORM_EVENT_INVALID = 0,
@ -192,10 +183,10 @@ typedef enum NormEventType
NORM_GRTT_UPDATED,
NORM_CC_ACTIVE,
NORM_CC_INACTIVE,
NORM_ACKING_NODE_NEW, // whe NormSetAutoAcking
NORM_ACKING_NODE_NEW, // whe NormSetAutoAcking
NORM_SEND_ERROR, // ICMP error (e.g. destination unreachable)
NORM_USER_TIMEOUT // issues when timeout set by NormSetUserTimer() expires
} NormEventType;
} NORM_API_LINKAGE NormEventType;
typedef struct
{
@ -204,51 +195,47 @@ typedef struct
NormNodeHandle sender;
NormObjectHandle object;
} NormEvent;
// For setting custom NORM_OBJECT_DATA alloc/free functions
typedef char* (*NormAllocFunctionHandle)(size_t);
typedef void (*NormFreeFunctionHandle)(char*);
/** NORM API General Initialization and Operation Functions */
NORM_API_LINKAGE
int NormGetVersion(int* major DEFAULT((int*)0),
int* minor DEFAULT((int*)0),
NORM_API_LINKAGE
int NormGetVersion(int* major DEFAULT((int*)0),
int* minor DEFAULT((int*)0),
int* patch DEFAULT((int*)0));
NORM_API_LINKAGE
NORM_API_LINKAGE
NormInstanceHandle NormCreateInstance(bool priorityBoost DEFAULT(false));
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormDestroyInstance(NormInstanceHandle instanceHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormStopInstance(NormInstanceHandle instanceHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormRestartInstance(NormInstanceHandle instanceHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSuspendInstance(NormInstanceHandle instanceHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormResumeInstance(NormInstanceHandle instanceHandle);
// This MUST be set to enable NORM_OBJECT_FILE reception!
// (otherwise received files are ignored)
NORM_API_LINKAGE
bool NormSetCacheDirectory(NormInstanceHandle instanceHandle,
bool NormSetCacheDirectory(NormInstanceHandle instanceHandle,
const char* cachePath);
// This call blocks until the next NormEvent is ready unless asynchronous
// notification is used (see below)
NORM_API_LINKAGE
// This call blocks until the next NormEvent is ready unless
// "waitForEvent" is set to "false"
NORM_API_LINKAGE
bool NormGetNextEvent(NormInstanceHandle instanceHandle, NormEvent* theEvent, bool waitForEvent DEFAULT(true));
// The "NormGetDescriptor()" function returns a HANDLE (WIN32) or
@ -266,56 +253,56 @@ typedef int NormDescriptor;
#endif // if/else WIN32/UNIX
extern NORM_API_LINKAGE
const NormDescriptor NORM_DESCRIPTOR_INVALID;
NORM_API_LINKAGE
NORM_API_LINKAGE
NormDescriptor NormGetDescriptor(NormInstanceHandle instanceHandle);
NORM_API_LINKAGE
void NormSetAllocationFunctions(NormInstanceHandle instance,
NormAllocFunctionHandle allocFunc,
NORM_API_LINKAGE
void NormSetAllocationFunctions(NormInstanceHandle instance,
NormAllocFunctionHandle allocFunc,
NormFreeFunctionHandle freeFunc);
/** NORM Session Creation and Control Functions */
// NORM Session Creation and Control Functions
NORM_API_LINKAGE
NORM_API_LINKAGE
NormSessionHandle NormCreateSession(NormInstanceHandle instanceHandle,
const char* sessionAddress,
UINT16 sessionPort,
NormNodeId localNodeId);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormDestroySession(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
NormInstanceHandle NormGetInstance(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
bool NormIsUnicastAddress(const char* address);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetUserData(NormSessionHandle sessionHandle, const void* userData);
NORM_API_LINKAGE
NORM_API_LINKAGE
const void* NormGetUserData(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetUserTimer(NormSessionHandle sessionHandle, double seconds);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormCancelUserTimer(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
NormNodeId NormGetLocalNodeId(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
bool NormGetAddress(NormSessionHandle sessionHandle,
char* addrBuffer,
char* addrBuffer,
unsigned int* bufferLen,
UINT16* port DEFAULT((UINT16*)0));
NORM_API_LINKAGE
UINT16 NormGetRxPort(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetTxPort(NormSessionHandle sessionHandle,
UINT16 txPortNumber,
bool enableReuse DEFAULT(false),
@ -335,12 +322,12 @@ void NormLimitObjectInfo(NormSessionHandle sessionHandle, bool state); // if tr
NORM_API_LINKAGE
bool NormPresetObjectInfo(NormSessionHandle sessionHandle, // FEC OTI is preset and not sent
unsigned long objectSize, // (most useful for NORM_OBJECT_STREAM)
UINT16 segmentSize,
UINT16 numData,
UINT16 segmentSize,
UINT16 numData,
UINT16 numParity);
// non-public on purpose
//NORM_API_LINKAGE
//void NormSetId(NormSessionHandle sessionHandle, NormNodeId normId);
NORM_API_LINKAGE
void NormSetId(NormSessionHandle sessionHandle, NormNodeId normId);
// This does not affect the rx_socket binding if already bound (sender or receiver already started)
// (i.e., just affects where NORM packets are sent)
@ -357,7 +344,7 @@ NORM_API_LINKAGE
bool NormTransferSender(NormSessionHandle sessionHandle, NormNodeHandle sender);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetRxPortReuse(NormSessionHandle sessionHandle,
bool enableReuse,
const char* rxBindAddress DEFAULT((const char*)0), // if non-NULL, bind() to <rxBindAddress>/<sessionPort>
@ -377,27 +364,27 @@ void NormSetEcnSupport(NormSessionHandle sessionHandle,
bool ignoreLoss DEFAULT(false), // With "ecnEnable", use ECN-only, ignoring packet loss
bool tolerateLoss DEFAULT(false)); // loss-tolerant congestion control, ecnEnable or not, ignoreLoss = false
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetMulticastInterface(NormSessionHandle sessionHandle,
const char* interfaceName);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetSSM(NormSessionHandle sessionHandle,
const char* sourceAddress);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetTTL(NormSessionHandle sessionHandle,
unsigned char ttl);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetTOS(NormSessionHandle sessionHandle,
unsigned char tos);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetLoopback(NormSessionHandle sessionHandle,
bool loopback);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetMulticastLoopback(NormSessionHandle sessionHandle,
bool loopback);
@ -407,13 +394,13 @@ bool NormSetFragmentation(NormSessionHandle sessionHandle,
bool fragmentation);
// Special functions for debug support
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetMessageTrace(NormSessionHandle sessionHandle, bool state);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetTxLoss(NormSessionHandle sessionHandle, double percent);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetRxLoss(NormSessionHandle sessionHandle, double percent);
NORM_API_LINKAGE
@ -449,7 +436,7 @@ NormSessionId NormGetRandomSessionId();
// This function has been updated so that 16-bit Reed-Solomon
// codecs can be accessed. This may cause an issue for linking
// to older versions of the NORM library
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormStartSender(NormSessionHandle sessionHandle,
NormSessionId instanceId,
UINT32 bufferSpace,
@ -458,59 +445,59 @@ bool NormStartSender(NormSessionHandle sessionHandle,
UINT16 numParity,
UINT8 fecId DEFAULT(0));
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormStopSender(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetTxRate(NormSessionHandle sessionHandle,
double bitsPerSecond);
NORM_API_LINKAGE
NORM_API_LINKAGE
double NormGetTxRate(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetTxSocketBuffer(NormSessionHandle sessionHandle,
unsigned int bufferSize);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetFlowControl(NormSessionHandle sessionHandle,
double flowControlFactor);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetCongestionControl(NormSessionHandle sessionHandle,
bool enable,
bool adjustRate DEFAULT(true));
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetTxRateBounds(NormSessionHandle sessionHandle,
double rateMin,
double rateMax);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetTxCacheBounds(NormSessionHandle sessionHandle,
NormSize sizeMax,
UINT32 countMin,
UINT32 countMax);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetAutoParity(NormSessionHandle sessionHandle,
unsigned char autoParity);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetGrttEstimate(NormSessionHandle sessionHandle,
double grttEstimate);
NORM_API_LINKAGE
double NormGetGrttEstimate(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetGrttMax(NormSessionHandle sessionHandle,
double grttMax);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetGrttProbingMode(NormSessionHandle sessionHandle,
NormProbingMode probingMode);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetGrttProbingInterval(NormSessionHandle sessionHandle,
double intervalMin,
double intervalMax);
@ -519,86 +506,86 @@ NORM_API_LINKAGE
void NormSetGrttProbingTOS(NormSessionHandle sessionHandle,
UINT8 probeTOS);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetBackoffFactor(NormSessionHandle sessionHandle,
double backoffFactor);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetGroupSize(NormSessionHandle sessionHandle,
unsigned int groupSize);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetTxRobustFactor(NormSessionHandle sessionHandle,
int robustFactor);
NORM_API_LINKAGE
NORM_API_LINKAGE
NormObjectHandle NormFileEnqueue(NormSessionHandle sessionHandle,
const char* fileName,
const char* infoPtr DEFAULT((const char*)0),
unsigned int infoLen DEFAULT(0));
NORM_API_LINKAGE
NORM_API_LINKAGE
NormObjectHandle NormDataEnqueue(NormSessionHandle sessionHandle,
const char* dataPtr,
UINT32 dataLen,
const char* infoPtr DEFAULT((const char*)0),
unsigned int infoLen DEFAULT(0));
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormRequeueObject(NormSessionHandle sessionHandle, NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
NormObjectHandle NormStreamOpen(NormSessionHandle sessionHandle,
UINT32 bufferSize,
const char* infoPtr DEFAULT((const char*)0),
unsigned int infoLen DEFAULT(0));
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormObjectSetUserData(NormObjectHandle objectHandle, const void* userData);
NORM_API_LINKAGE
NORM_API_LINKAGE
const void* NormObjectGetUserData(NormObjectHandle objectHandle);
// TBD - we should add a "bool watermark" option to "graceful" stream closure???
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormStreamClose(NormObjectHandle streamHandle, bool graceful DEFAULT(false));
NORM_API_LINKAGE
unsigned int NormGetStreamBufferSegmentCount(unsigned int bufferBytes, UINT16 segmentSize, UINT16 blockSize);
NORM_API_LINKAGE
NORM_API_LINKAGE
unsigned int NormStreamWrite(NormObjectHandle streamHandle,
const char* buffer,
unsigned int numBytes);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormStreamFlush(NormObjectHandle streamHandle,
bool eom DEFAULT(false),
NormFlushMode flushMode DEFAULT(NORM_FLUSH_PASSIVE));
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormStreamSetAutoFlush(NormObjectHandle streamHandle,
NormFlushMode flushMode);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormStreamSetPushEnable(NormObjectHandle streamHandle,
bool pushEnable);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormStreamHasVacancy(NormObjectHandle streamHandle);
NORM_API_LINKAGE
unsigned int NormStreamGetVacancy(NormObjectHandle streamHandle, unsigned int bytesWanted = 0);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormStreamMarkEom(NormObjectHandle streamHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetWatermark(NormSessionHandle sessionHandle,
NormObjectHandle objectHandle,
bool overrideFlush DEFAULT(false));
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetWatermarkEx(NormSessionHandle sessionHandle,
NormObjectHandle objectHandle,
const char* buffer,
@ -606,17 +593,17 @@ bool NormSetWatermarkEx(NormSessionHandle sessionHandle,
bool overrideFlush DEFAULT(false));
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormResetWatermark(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormCancelWatermark(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormAddAckingNode(NormSessionHandle sessionHandle,
NormNodeId nodeId);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormRemoveAckingNode(NormSessionHandle sessionHandle,
NormNodeId nodeId);
@ -628,11 +615,11 @@ NORM_API_LINKAGE
void NormSetAutoAckingNodes(NormSessionHandle sessionHandle,
NormTrackingStatus trackingStatus);
NORM_API_LINKAGE
NORM_API_LINKAGE
NormAckingStatus NormGetAckingStatus(NormSessionHandle sessionHandle,
NormNodeId nodeId DEFAULT(NORM_NODE_ANY));
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormGetNextAckingNode(NormSessionHandle sessionHandle,
NormNodeId* nodeId,
NormAckingStatus* ackingStatus DEFAULT(0));
@ -643,77 +630,77 @@ bool NormGetAckEx(NormSessionHandle sessionHandle,
char* buffer,
unsigned int* buflen);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSendCommand(NormSessionHandle sessionHandle,
const char* cmdBuffer,
unsigned int cmdLength,
bool robust DEFAULT(false));
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormCancelCommand(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetSynStatus(NormSessionHandle sessionHandle, bool state);
/* NORM Receiver Functions */
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormStartReceiver(NormSessionHandle sessionHandle,
UINT32 bufferSpace);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormStopReceiver(NormSessionHandle sessionHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetRxCacheLimit(NormSessionHandle sessionHandle,
unsigned short countMax);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormSetRxSocketBuffer(NormSessionHandle sessionHandle,
unsigned int bufferSize);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetSilentReceiver(NormSessionHandle sessionHandle,
bool silent,
int maxDelay DEFAULT(-1));
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetDefaultUnicastNack(NormSessionHandle sessionHandle,
bool unicastNacks);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormNodeSetUnicastNack(NormNodeHandle remoteSender,
bool unicastNacks);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetDefaultSyncPolicy(NormSessionHandle sessionHandle,
NormSyncPolicy syncPolicy);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetDefaultNackingMode(NormSessionHandle sessionHandle,
NormNackingMode nackingMode);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormNodeSetNackingMode(NormNodeHandle remoteSender,
NormNackingMode nackingMode);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormObjectSetNackingMode(NormObjectHandle objectHandle,
NormNackingMode nackingMode);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetDefaultRepairBoundary(NormSessionHandle sessionHandle,
NormRepairBoundary repairBoundary);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormNodeSetRepairBoundary(NormNodeHandle remoteSender,
NormRepairBoundary repairBoundary);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormSetDefaultRxRobustFactor(NormSessionHandle sessionHandle,
int robustFactor);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormNodeSetRxRobustFactor(NormNodeHandle remoteSender,
int robustFactor);
@ -725,90 +712,90 @@ bool NormPreallocateRemoteSender(NormSessionHandle sessionHandle,
UINT16 numParity,
unsigned int streamBufferSize DEFAULT(0));
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormStreamRead(NormObjectHandle streamHandle,
char* buffer,
unsigned int* numBytes);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormStreamSeekMsgStart(NormObjectHandle streamHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
UINT32 NormStreamGetReadOffset(NormObjectHandle streamHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
UINT32 NormStreamGetBufferUsage(NormObjectHandle streamHandle);
/** NORM Object Functions */
NORM_API_LINKAGE
NORM_API_LINKAGE
NormObjectType NormObjectGetType(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormObjectHasInfo(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
UINT16 NormObjectGetInfoLength(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
UINT16 NormObjectGetInfo(NormObjectHandle objectHandle,
char* buffer,
UINT16 bufferLen);
NORM_API_LINKAGE
NORM_API_LINKAGE
NormSize NormObjectGetSize(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
NormSize NormObjectGetBytesPending(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormObjectCancel(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormObjectRetain(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormObjectRelease(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormFileGetName(NormObjectHandle fileHandle,
char* nameBuffer,
unsigned int bufferLen);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormFileRename(NormObjectHandle fileHandle,
const char* fileName);
NORM_API_LINKAGE
NORM_API_LINKAGE
const char* NormDataAccessData(NormObjectHandle objectHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
char* NormDataDetachData(NormObjectHandle objectHandle);
NORM_API_LINKAGE
char* NormAlloc(size_t numBytes);
NORM_API_LINKAGE
char* NormAlloc(size_t numBytes);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormFree(char* dataPtr);
NORM_API_LINKAGE
NORM_API_LINKAGE
NormNodeHandle NormObjectGetSender(NormObjectHandle objectHandle);
/** NORM Node Functions */
NORM_API_LINKAGE
NORM_API_LINKAGE
NormNodeId NormNodeGetId(NormNodeHandle nodeHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
bool NormNodeGetAddress(NormNodeHandle nodeHandle,
char* addrBuffer,
char* addrBuffer,
unsigned int* bufferLen,
UINT16* port DEFAULT((UINT16*)0));
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormNodeSetUserData(NormNodeHandle nodeHandle, const void* userData);
NORM_API_LINKAGE
NORM_API_LINKAGE
const void* NormNodeGetUserData(NormNodeHandle nodeHandle);
NORM_API_LINKAGE
@ -836,10 +823,10 @@ void NormNodeFreeBuffers(NormNodeHandle remoteSender);
NORM_API_LINKAGE
void NormNodeDelete(NormNodeHandle remoteSender);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormNodeRetain(NormNodeHandle nodeHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
void NormNodeRelease(NormNodeHandle nodeHandle);
/** Some experimental functions */
@ -847,7 +834,7 @@ void NormNodeRelease(NormNodeHandle nodeHandle);
NORM_API_LINKAGE
void NormReleasePreviousEvent(NormInstanceHandle instanceHandle);
NORM_API_LINKAGE
NORM_API_LINKAGE
UINT32 NormCountCompletedObjects(NormSessionHandle sessionHandle);
@ -861,7 +848,7 @@ NORM_API_LINKAGE
bool NormNodeAllowSender(NormNodeId senderId);
NORM_API_LINKAGE
bool NormNodeDenySender(NormNodeId senderId);
bool NormNodeDenySender(NormNodeId senderId);
#ifdef __cplusplus
} // end extern "C"

0
include/normEncoder.h Normal file → Executable file
View File

0
include/normEncoderMDP.h Normal file → Executable file
View File

0
include/normEncoderRS16.h Normal file → Executable file
View File

0
include/normEncoderRS8.h Normal file → Executable file
View File

0
include/normFile.h Normal file → Executable file
View File

16
include/normMessage.h Normal file → Executable file
View File

@ -69,12 +69,12 @@ inline UINT16 NormQuantizeLoss(double lossFraction)
lossFraction = MIN(lossFraction, 65535.0);
return (UINT16)lossFraction;
} // end NormQuantizeLossFraction()
inline double NormUnquantizeLoss(UINT16 lossQuantized)
{
return (((double)lossQuantized) / 65535.0);
} // end NormUnquantizeLossFraction()
// Extended precision Norm loss quantize/unquantize with
// 32-bit precision (needed for low BER, high bandwidth*delay)
inline UINT32 NormQuantizeLoss32(double lossFraction)
@ -195,13 +195,11 @@ class NormObjectId
UINT16 diff = value - id.value;
return ((diff > 0x8000) || ((0x8000 == diff) && (value > id.value)));
}
bool operator>(const NormObjectId& id) const
{
UINT16 diff = id.value - value;
return ((diff > 0x8000) || ((0x8000 == diff) && (id.value > value)));
}
bool operator<=(const NormObjectId& id) const
{return ((value == id.value) || (*this < id));}
bool operator>=(const NormObjectId& id) const
@ -935,11 +933,11 @@ class NormFtiExtension5 : public NormHeaderExtension
private:
enum
{
OBJ_SIZE_MSB_OFFSET = (CONTENT_OFFSET)/2, // UINT16 offset
OBJ_SIZE_LSB_OFFSET = ((OBJ_SIZE_MSB_OFFSET*2)+2)/4,
SEG_SIZE_OFFSET = ((OBJ_SIZE_LSB_OFFSET*4)+4)/2,
FEC_NDATA_OFFSET = ((SEG_SIZE_OFFSET+1)*2),
FEC_NPARITY_OFFSET = (FEC_NDATA_OFFSET+1)
OBJ_SIZE_MSB_OFFSET = (CONTENT_OFFSET)/2, // UINT16 offset
OBJ_SIZE_LSB_OFFSET = ((OBJ_SIZE_MSB_OFFSET*2)+2)/4,// UINT32 offset
SEG_SIZE_OFFSET = ((OBJ_SIZE_LSB_OFFSET*4)+4)/2, // UINT16 offset
FEC_NDATA_OFFSET = ((SEG_SIZE_OFFSET+1)*2), // UINT8 offset
FEC_NPARITY_OFFSET = (FEC_NDATA_OFFSET+1) // UINT8 offset
};
}; // end class NormFtiExtension5
@ -1803,7 +1801,7 @@ class NormCCFeedbackExtension : public NormHeaderExtension
CC_LOSS_OFFSET = (CC_RTT_OFFSET + 1)/2,
CC_RATE_OFFSET = ((CC_LOSS_OFFSET*2)+2)/2,
//CC_RESERVED_OFFSET = ((CC_RATE_OFFSET*2)+2)/2
CC_LOSS_EX_OFFSET = ((CC_RATE_OFFSET*2)+2)/2 // extended precision loss estimate (non-RFC5940 compliant, but compatible)
CC_LOSS_EX_OFFSET = ((CC_RATE_OFFSET*2)+2)/2 // extended precision loss estimate (non-RFC5740 compliant, but compatible)
};
}; // end class NormCCFeedbackExtension

24
include/normNode.h Normal file → Executable file
View File

@ -188,6 +188,28 @@ class NormLossEstimator2
}; // end class NormLossEstimator2
class NormCongestionDetector
{
// This class implements a delay-based congestion indicator
// based on feedback from NORM receivers. Similar to loss-based
// congestion detection, this detector monitors the history of
// RTT measurement
// NOTES:
// 1) One challenge to consider is reverse path contribution
// to RTT may create "false positives" on RTT change detection.
// A technique to mitigate is to use reference timing that the
// receiver can establish on expected sender packet arrivals
// given rate information to helps separate sender->receiver
// contribution to RTT versus the reverse path receiver->sender
// aspect. E.g., the receiver could compare the stats of arriving
// sender packets in reference to advertised rate to have an indication
// of increasing (or decreasing) sender->receiver latency.
//
// 2)
//
}; // end class NormCongestionDetector
class NormAckingNode : public NormNode
{
public:
@ -556,7 +578,7 @@ class NormSenderNode : public NormNode, public ProtoTree::Item
UINT8 GetGrttQuantized() const
{return grtt_quantized;}
UINT8 GetBackoffFactor() const
double GetBackoffFactor() const
{return backoff_factor;}
UINT8 GetGroupSizeQuantized() const
{return gsize_quantized;}

2
include/normObject.h Normal file → Executable file
View File

@ -30,6 +30,7 @@ class NormObject
enum CheckLevel
{
BLIND_CHECK,
TO_OBJECT,
THRU_INFO,
TO_BLOCK,
@ -360,6 +361,7 @@ class NormFileObject : public NormObject
const char* infoPtr = NULL,
UINT16 infoLen = 0);
bool Accept(const char* thePath);
void CloseFile();
void Close();
const char* GetPath() {return path;}

0
include/normPostProcess.h Normal file → Executable file
View File

0
include/normSegment.h Normal file → Executable file
View File

0
include/normSession.h Normal file → Executable file
View File

0
include/normSimAgent.h Normal file → Executable file
View File

2
include/normVersion.h Normal file → Executable file
View File

@ -36,6 +36,6 @@
#ifndef _NORM_VERSION
#define _NORM_VERSION
#define VERSION "1.5.9"
#define VERSION "1.5.10"
#endif // _NORM_VERSION

0
makefiles/Makefile.arm-linux Normal file → Executable file
View File

23
makefiles/Makefile.common Normal file → Executable file
View File

@ -188,7 +188,8 @@ normStreamer: $(STREAMER_OBJ) libnorm.a $(LIBPROTO)
cp $@ ../bin/$@
# (normCast) file sender/receiver
CAST_SRC = $(EXAMPLE)/normCast.cpp
CAST_SRC = $(EXAMPLE)/normCast.cpp $(COMMON)/normPostProcess.cpp \
$(UNIX)/unixPostProcess.cpp
CAST_OBJ = $(CAST_SRC:.cpp=.o)
normCast: $(CAST_OBJ) libnorm.a $(LIBPROTO)
@ -196,6 +197,26 @@ normCast: $(CAST_OBJ) libnorm.a $(LIBPROTO)
mkdir -p ../bin
cp $@ ../bin/$@
# (normCastApp) file sender/receiver
CASTAPP_SRC = $(EXAMPLE)/normCastApp.cpp $(COMMON)/normPostProcess.cpp \
$(UNIX)/unixPostProcess.cpp
CASTAPP_OBJ = $(CASTAPP_SRC:.cpp=.o)
normCastApp: $(CASTAPP_OBJ) libnorm.a $(LIBPROTO)
$(CC) $(CFLAGS) -o $@ $(CASTAPP_OBJ) $(LDFLAGS) libnorm.a $(LIBPROTO) $(LIBS)
mkdir -p ../bin
cp $@ ../bin/$@
# (chant) NORM command-line chat sender/receiver
CHANT_SRC = $(EXAMPLE)/chant.cpp
CHANT_OBJ = $(CHANT_SRC:.cpp=.o)
chant: $(CHANT_OBJ) libnorm.a $(LIBPROTO)
$(CC) $(CFLAGS) -o $@ $(CHANT_OBJ) $(LDFLAGS) libnorm.a $(LIBPROTO) $(LIBS)
mkdir -p ../bin
cp $@ ../bin/$@
# These are the new "NormSocket" API extension examples
SERVER_SRC = $(EXAMPLE)/normServer.cpp $(EXAMPLE)/normSocket.cpp
SERVER_OBJ = $(SERVER_SRC:.cpp=.o)

0
makefiles/Makefile.freebsd Normal file → Executable file
View File

0
makefiles/Makefile.hpux Normal file → Executable file
View File

0
makefiles/Makefile.iphone Normal file → Executable file
View File

0
makefiles/Makefile.linux Normal file → Executable file
View File

4
makefiles/Makefile.macosx Normal file → Executable file
View File

@ -44,8 +44,10 @@ SYSTEM_SRC = ../protolib/src/unix/bpfCap.cpp
# The "SYSTEM" keyword can be used for dependent makes
SYSTEM = macosx
# TBD - provide means to build universal Mac OSX library (x86/arm64)
CC = g++
SYSTEM_CFLAGS = -Wall -Wcast-align -fPIC -arch x86_64
SYSTEM_CFLAGS = -Wall -Wcast-align -fPIC
SYSTEM_SOFLAGS = -dynamiclib
SYSTEM_SOEXT = dylib
RANLIB = ranlib

0
makefiles/Makefile.mklinux Normal file → Executable file
View File

0
makefiles/Makefile.netbsd Normal file → Executable file
View File

0
makefiles/Makefile.sgi Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More