diff --git a/Tobi_squared.png b/Tobi_squared.png new file mode 100644 index 0000000000000000000000000000000000000000..2a9f141da838dcfce744ed0ffb3bb12f4f04d6ac Binary files /dev/null and b/Tobi_squared.png differ diff --git a/assignments/ReportingForDuty.md b/assignments/ReportingForDuty.md index 2dd3bf098912c6a64e6de341d0d40d98c496723a..68b2788da2e586672663df83ecacebc909588baa 100644 --- a/assignments/ReportingForDuty.md +++ b/assignments/ReportingForDuty.md @@ -25,6 +25,7 @@ More information on your use of Git is in the parent directory [README.md](../.. - Christopher Cannon - Bill Mahan + --- ### 2019 @@ -44,5 +45,3 @@ More information on your use of Git is in the parent directory [README.md](../.. - Bert Knobeloch - Tobias Brennenstuhl aka Sir Tobi - - diff --git a/assignments/build.xml b/assignments/build.xml index 2b8c338bb1277d3f5f33939476fdbfda4bdca00e..427209286b71ecf9a9b0e210292b9ee53274a4ee 100644 --- a/assignments/build.xml +++ b/assignments/build.xml @@ -7,7 +7,7 @@ <!-- the Compile on Save feature is turned off for the project. --> <!-- You can turn off the Compile on Save (or Deploy on Save) setting --> <!-- in the project's Project Properties dialog box.--> -<project name="MV3500_Deliverables" default="default" basedir="."> +<project name="MV3500 assignments" default="default" basedir="."> <description>Builds, tests, and runs the MV3500 project assignments</description> <import file="nbproject/build-impl.xml"/> <!-- diff --git a/assignments/nbproject/genfiles.properties b/assignments/nbproject/genfiles.properties index 81515a0c3dec1f6ab1d66241d0881f2f5426139c..1e5930a6e750414589c4a0e3c59358da0a8ace52 100644 --- a/assignments/nbproject/genfiles.properties +++ b/assignments/nbproject/genfiles.properties @@ -1,5 +1,5 @@ -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=5eaf4250 -nbproject/build-impl.xml.script.CRC32=013963da -nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=ad8aeeb2 +nbproject/build-impl.xml.script.CRC32=bd12e823 +nbproject/build-impl.xml.stylesheet.CRC32=f89f7d21@1.95.0.48 diff --git a/assignments/nbproject/project.properties b/assignments/nbproject/project.properties index 05c6f493d71c7f76c47f470d33e5afb981989e3e..6e6876fa79820b0ea57290915c0a9c2e2b7dd733 100644 --- a/assignments/nbproject/project.properties +++ b/assignments/nbproject/project.properties @@ -1,130 +1,128 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.desc=Student assignments performed as part of course Networked Graphics MV3500 -application.homepage=https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments -application.title=Networked Graphics MV3500 assignments -application.vendor=Don Brutzman -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.modulepath=\ - ${run.modulepath} -debug.test.classpath=\ - ${run.test.classpath} -debug.test.modulepath=\ - ${run.test.modulepath} -# Files in build.classes.dir which should be excluded from distribution jar -dist.archive.excludes= -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/Networked_Graphics_MV3500_assignments.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.commons-io-2.6.jar=../lib/commons-io-2.6.jar -file.reference.dis-enums-1.3.jar=../lib/dis-enums-1.3.jar -file.reference.guava-28.0-jre.jar=../lib/guava-28.0-jre.jar -file.reference.open-dis7-entities-all.jar=../lib/open-dis7-entities-all.jar -file.reference.open-dis7-java.jar=../lib/open-dis7-java.jar -file.reference.open-dis7-javadoc.jar=../lib/open-dis7-javadoc.jar -file.reference.open-dis7-source.jar=../lib/open-dis7-source.jar -file.reference.open-dis_4.16.jar=../lib/open-dis_4.16.jar -includes=** -jar.archive.disabled=${jnlp.enabled} -jar.compress=false -jar.index=${jnlp.enabled} -javac.classpath=\ - ${file.reference.open-dis7-entities-all.jar}:\ - ${file.reference.open-dis7-java.jar}:\ - ${file.reference.open-dis7-javadoc.jar}:\ - ${file.reference.open-dis7-source.jar}:\ - ${file.reference.commons-io-2.6.jar}:\ - ${file.reference.guava-28.0-jre.jar}:\ - ${file.reference.open-dis_4.16.jar}:\ - ${file.reference.dis-enums-1.3.jar} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.external.vm=true -javac.modulepath= -javac.processormodulepath= -javac.processorpath=\ - ${javac.classpath} -javac.source=1.8 -javac.target=1.8 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javac.test.modulepath=\ - ${javac.modulepath} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.html5=false -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.reference.open-dis7-java.jar=../lib/open-dis7-javadoc.jar -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -jlink.launcher=false -jlink.launcher.name=Networked_Graphics_MV3500_assignments -jnlp.codebase.type=no.codebase -jnlp.descriptor=application -jnlp.enabled=false -jnlp.mixed.code=default -jnlp.offline-allowed=false -jnlp.signed=false -jnlp.signing= -jnlp.signing.alias= -jnlp.signing.keystore= -main.class=MV3500Cohort2020JulySeptember.homework1.WeissenbergerTcpExample1Telnet -# Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found. -manifest.custom.application.library.allowable.codebase= -# Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts. -manifest.custom.caller.allowable.codebase= -# Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed -manifest.custom.codebase= -# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions) -manifest.custom.permissions= -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -project.licensePath=../license.txt -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project. -# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. -# To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs= -run.modulepath=\ - ${javac.modulepath} -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -run.test.modulepath=\ - ${javac.test.modulepath} -source.encoding=UTF-8 -source.reference.open-dis7-java.jar=../lib/open-dis7-source.jar -src.dir=src -test.src.dir=test +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.desc=Student assignments performed as part of NPS course Networked Graphics MV3500. This course is an introduction to network communications in simulation applications. Topics include an introduction to the TCP/IP protocol stack; TCP/IP socket communications, including TCP, UDP, and multicast; and protocol design issues, with emphasis on Distributed Interactive Simulation (DIS) Protocol and High Level Architecture (HLA). Course emphasis is on creation and testing of network programming network code and web-browser applications. +application.homepage=https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments +application.splash=../..\\NetworkedGraphicsMV3500\\documentation\\images\\OpenDisSurferDude.png +application.title=NPS Networked Graphics MV3500 assignments +application.vendor=Don Brutzman +auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.modulepath=\ + ${run.modulepath} +debug.test.classpath=\ + ${run.test.classpath} +debug.test.modulepath=\ + ${run.test.modulepath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Networked_Graphics_MV3500_assignments.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.commons-io-2.6.jar=../lib/commons-io-2.6.jar +file.reference.dis-enums-1.3.jar=../lib/dis-enums-1.3.jar +file.reference.guava-28.0-jre.jar=../lib/guava-28.0-jre.jar +file.reference.open-dis7-enumerations-classes.jar=../lib/open-dis7-enumerations-classes.jar +file.reference.open-dis7-pdus-classes.jar=../lib/open-dis7-pdus-classes.jar +file.reference.open-dis_4.16.jar=../lib/open-dis_4.16.jar +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=false +jar.index=${jnlp.enabled} +javac.classpath=\ + ${file.reference.open-dis7-enumerations-classes.jar}:\ + ${file.reference.open-dis7-pdus-classes.jar}:\ + ${file.reference.commons-io-2.6.jar}:\ + ${file.reference.guava-28.0-jre.jar}:\ + ${file.reference.open-dis_4.16.jar}:\ + ${file.reference.dis-enums-1.3.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=true +javac.modulepath= +javac.processormodulepath= +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.modulepath=\ + ${javac.modulepath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=true +javadoc.encoding=${source.encoding} +javadoc.html5=false +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.reference.open-dis7-enumerations-classes.jar=../lib/open-dis7-enumerations-javadoc.jar +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle=Networked Graphics MV3500 NPS +jlink.launcher=false +jlink.launcher.name=Networked_Graphics_MV3500_assignments +jnlp.codebase.type=no.codebase +jnlp.descriptor=application +jnlp.enabled=false +jnlp.mixed.code=default +jnlp.offline-allowed=false +jnlp.signed=false +jnlp.signing= +jnlp.signing.alias= +jnlp.signing.keystore= +main.class=MV3500Cohort2020JulySeptember.homework1.WeissenbergerTcpExample1Telnet +# Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found. +manifest.custom.application.library.allowable.codebase= +# Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts. +manifest.custom.caller.allowable.codebase= +# Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed +manifest.custom.codebase= +# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions) +manifest.custom.permissions= +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +project.licensePath=../license.txt +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.modulepath=\ + ${javac.modulepath} +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +run.test.modulepath=\ + ${javac.test.modulepath} +source.encoding=UTF-8 +source.reference.open-dis7-enumerations-classes.jar=../lib/open-dis7-enumerations-source.jar +src.dir=src +test.src.dir=test diff --git a/assignments/nbproject/project.xml b/assignments/nbproject/project.xml index a8deed1628f74f99861205f0c0c7df64c605b09b..042a5d4de46fba4c89134e0e68f7624366a0b5cb 100644 --- a/assignments/nbproject/project.xml +++ b/assignments/nbproject/project.xml @@ -1,27 +1,27 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://www.netbeans.org/ns/project/1"> - <type>org.netbeans.modules.java.j2seproject</type> - <configuration> - <data xmlns="http://www.netbeans.org/ns/j2se-project/3"> - <name>Networked Graphics MV3500 assignments</name> - <source-roots> - <root id="src.dir"/> - </source-roots> - <test-roots> - <root id="test.src.dir"/> - </test-roots> - </data> - <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1"> - <word>deliverables</word> - <word>https</word> - <word>localhost</word> - <word>multicast</word> - <word>Netbeans</word> - <word>README</word> - <word>UML</word> - <word>unicast</word> - <word>wikipedia</word> - <word>Wireshark</word> - </spellchecker-wordlist> - </configuration> -</project> +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://www.netbeans.org/ns/project/1"> + <type>org.netbeans.modules.java.j2seproject</type> + <configuration> + <data xmlns="http://www.netbeans.org/ns/j2se-project/3"> + <name>Networked Graphics MV3500 assignments</name> + <source-roots> + <root id="src.dir"/> + </source-roots> + <test-roots> + <root id="test.src.dir"/> + </test-roots> + </data> + <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1"> + <word>deliverables</word> + <word>https</word> + <word>localhost</word> + <word>multicast</word> + <word>Netbeans</word> + <word>README</word> + <word>UML</word> + <word>unicast</word> + <word>wikipedia</word> + <word>Wireshark</word> + </spellchecker-wordlist> + </configuration> +</project> diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronEntityStatePduCreator.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronEntityStatePduCreator.java index 855dd84aa16cd0cac511c23f1d2f8bdf35ee27a3..34508ef781c51af57a2c5f2583ede88c1b27a6a2 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronEntityStatePduCreator.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronEntityStatePduCreator.java @@ -1,7 +1,6 @@ package MV3500Cohort2019JulySeptember.homework4.Boron; -import edu.nps.moves.dis7.*; -import edu.nps.moves.dis7.enumerations.DISPDUType; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.ForceID; /** @@ -22,7 +21,7 @@ public class BoronEntityStatePduCreator { * @param l is a double array containing position x,y,z coordinates * @param v is a float array containing x,y,z velocity values * @param o is a float array containing phi, psi, and theta orientation values - * @returns a new EntityStatePdu with minimal information + * @return a new EntityStatePdu with minimal information */ public EntityStatePdu newPDU(short s, ForceID fid, double [] l, float[] v, float[] o) { diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronPduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronPduReceiver.java index 70dee43862fe0b9ee68409863b1629a37db028a2..9e35f29175237a525c43b2036e9319059a7965cb 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronPduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronPduReceiver.java @@ -3,7 +3,7 @@ package MV3500Cohort2019JulySeptember.homework4.Boron; import java.net.*; import java.io.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; import static edu.nps.moves.dis7.enumerations.DISPDUType.*; import edu.nps.moves.dis7.utilities.*; @@ -79,8 +79,7 @@ public class BoronPduReceiver //If PDU is an Entity State PDU, print location of entity if (currentPduType == ENTITY_STATE) { - EntityStatePdu espdu = new EntityStatePdu(); - espdu = (EntityStatePdu) pdu; + EntityStatePdu espdu = (EntityStatePdu) pdu; Vector3Double location = espdu.getEntityLocation(); System.out.println("Entity is at position: x = " + location.getX() + ", y = " + location.getY() + ", z = " + location.getZ()); diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronPduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronPduSender.java index fccec68651b4c0828904846b2ad4afc72949e4b1..e22a07f0511d983951a3cace442f6625bbc3c1ab 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronPduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Boron/BoronPduSender.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; /** diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/BrennenstuhlEspduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/BrennenstuhlEspduReceiver.java index 0d44068f66b9f46666dc2294bb3d687bf46e2b7f..7e9ad40f5b53e141acd427d5e403a8ddb033c85b 100755 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/BrennenstuhlEspduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/BrennenstuhlEspduReceiver.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.*; /** diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/BrennenstuhlEspduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/BrennenstuhlEspduSender.java index 3adc6b233dc2c7a325ae846522deecb6385dc653..5f858f444529d16e5bc751d5556be77c286fe80b 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/BrennenstuhlEspduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/BrennenstuhlEspduSender.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.*; import edu.nps.moves.dis7.enumerations.Country; import edu.nps.moves.dis7.enumerations.EntityKind; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/Version2/AllPduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/Version2/AllPduReceiver.java index 9fbb9159591ab4934fe2ede79a6a11a79dad894a..abe2879360309e629acfb4b8a78fba3139ca6320 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/Version2/AllPduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/Version2/AllPduReceiver.java @@ -1,9 +1,9 @@ -package MV3500Cohort2019JulySeptember.homework4.Brennenstuhl.test; +package MV3500Cohort2019JulySeptember.homework4.Brennenstuhl.Version2; import java.net.*; import java.io.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; import edu.nps.moves.dis7.utilities.*; import java.util.ArrayList; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/Version2/AllPduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/Version2/AllPduSender.java index a1607920c29d1843ec83854ee99368a7e301e8e9..7b79f2fdf33a7cda3109041224ad59d4f99dcd27 100755 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/Version2/AllPduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Brennenstuhl/Version2/AllPduSender.java @@ -1,11 +1,10 @@ -package MV3500Cohort2019JulySeptember.homework4.Brennenstuhl.test; +package MV3500Cohort2019JulySeptember.homework4.Brennenstuhl.Version2; import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; -import edu.nps.moves.dis7.enumerations.*; +import edu.nps.moves.dis7.pdus.*; /** * This is an example that sends many/most types of PDUs. Useful for testing standards @@ -59,7 +58,7 @@ public class AllPduSender //*************************************************************************** CommentPdu newCommentPdu = new CommentPdu(); - ArrayList<VariableDatum> payloadList = new ArrayList<VariableDatum>(); + ArrayList<VariableDatum> payloadList = new ArrayList<>(); ArrayList<String> commentsList = new ArrayList<>(); commentsList.add("Hello CommentPDU"); diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduListenerSaver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduListenerSaver.java index 2c7c6a144e43f29b9dc169e0bdc3907c84452a32..7f5baad906d83a3e9e4933faee96ad210303bc94 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduListenerSaver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduListenerSaver.java @@ -4,7 +4,7 @@ */ package MV3500Cohort2019JulySeptember.homework4.Fetterolf; -import edu.nps.moves.dis7.util.playerrecorder.Recorder; +import edu.nps.moves.dis7.utilities.stream.PduRecorder; import java.io.IOException; import java.util.Scanner; @@ -51,7 +51,7 @@ public class FetterolfPduListenerSaver { System.out.println("Beginning pdu save to directory " + outDir); try { - Recorder recorder = new Recorder(outDir, mcast, port); + PduRecorder recorder = new PduRecorder(outDir, mcast, port); recorder.startResume(); mystate state = mystate.RUNNING; @@ -76,7 +76,7 @@ public class FetterolfPduListenerSaver { break; } } - System.out.println("Ending pdu save to " + recorder.getLogFile()); + System.out.println("Ending pdu save to " + recorder.getLogFilePath()); } catch (IOException ex) { System.err.println("*** Exception: " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage()); } diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduReceiver.java index cf2f1e99151d6d5ff92d80e6ec8b24e39e834cff..703d3cc725ee1fb1c893d1d382300d5544481648 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduReceiver.java @@ -3,7 +3,7 @@ package MV3500Cohort2019JulySeptember.homework4.Fetterolf; import java.net.*; import java.io.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; import edu.nps.moves.dis7.utilities.*; import java.util.ArrayList; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduSender.java index af97291ed05ce19edf6172e52853261111f64bd2..cf4d9649f8bbdb49fac1d05f759ef68a4c6ea939 100755 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Fetterolf/FetterolfPduSender.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; /** @@ -104,7 +104,7 @@ public class FetterolfPduSender { // see Garrett Loffelman and Pete Severson's code for OpenDis version 4 example // https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments/src/MV3500Cohort2018JulySeptember/projects/LoeffelmanSeverson CommentPdu newCommentPdu = new CommentPdu(); - ArrayList<VariableDatum> payloadList = new ArrayList<VariableDatum>(); + ArrayList<VariableDatum> payloadList = new ArrayList<>(); ArrayList<String> commentsList = new ArrayList<>(); commentsList.add("Hello CommentPDU"); @@ -117,7 +117,7 @@ public class FetterolfPduSender { for (String comment : commentsList) { VariableDatum newVariableDatum = new VariableDatum(); newVariableDatum.setVariableDatumValue(comment.getBytes()); // conversion - newVariableDatum.setVariableDatumLength(comment.getBytes().length * 8); // bits, not bytes, see spec and javadoc + newVariableDatum.setVariableDatumLengthInBits(comment.getBytes().length * 8); // bits, not bytes, see spec and javadoc // alternatively, you do not need to set this and the marshaller will figure it out from the byte array // (see javadoc for VariableDatum.setVariableDatumLength()) payloadList.add(newVariableDatum); diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Knobeloch/Knobeloch_PduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Knobeloch/Knobeloch_PduReceiver.java index b96efe5114e18826401bc8fca8d197f0498e6d8b..c062785c8bae2a4a2e40e06ed69c5729cb206518 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Knobeloch/Knobeloch_PduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Knobeloch/Knobeloch_PduReceiver.java @@ -3,7 +3,7 @@ package MV3500Cohort2019JulySeptember.homework4.Knobeloch; import java.net.*; import java.io.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; import edu.nps.moves.dis7.utilities.*; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Knobeloch/Knobeloch_PduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Knobeloch/Knobeloch_PduSender.java index ad0139b5dec0f91c10c5a012aa629e03794a9ff1..ca64e3c2c1b6b7a8254bb4d9f807436e9087a5cc 100755 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Knobeloch/Knobeloch_PduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Knobeloch/Knobeloch_PduSender.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; import java.util.logging.Level; import java.util.logging.Logger; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/McCann/McCannPduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/McCann/McCannPduReceiver.java index c15faf1e83b7c82493dcfa5d9a1070c5e53d4cef..e3f076bc44a0b453ee3130af172a6c8a6c1f3bc0 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/McCann/McCannPduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/McCann/McCannPduReceiver.java @@ -3,7 +3,7 @@ package MV3500Cohort2019JulySeptember.homework4.McCann; import java.net.*; import java.io.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; import edu.nps.moves.dis7.utilities.*; import java.util.ArrayList; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/McCann/McCannPduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/McCann/McCannPduSender.java index 3585cf0cb28870d9f7ff841b314739c90c337fc5..91bb956b09ff7a04231d1b0499438c690dd54c63 100755 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/McCann/McCannPduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/McCann/McCannPduSender.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; /** @@ -374,7 +374,7 @@ public class McCannPduSender // https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments/src/MV3500Cohort2018JulySeptember/projects/LoeffelmanSeverson CommentPdu newCommentPdu = new CommentPdu(); - ArrayList<VariableDatum> payloadList = new ArrayList<VariableDatum>(); + ArrayList<VariableDatum> payloadList = new ArrayList<>(); ArrayList<String> commentsList = new ArrayList<>(); commentsList.add("Hello CommentPDU"); @@ -387,7 +387,7 @@ public class McCannPduSender { VariableDatum newVariableDatum = new VariableDatum(); newVariableDatum.setVariableDatumValue (comment.getBytes()); // conversion - newVariableDatum.setVariableDatumLength(comment.getBytes().length * 8); // bits, not bytes, see spec and javadoc + newVariableDatum.setVariableDatumLengthInBits(comment.getBytes().length * 8); // bits, not bytes, see spec and javadoc // alternatively, you do not need to set this and the marshaller will figure it out from the byte array // (see javadoc for VariableDatum.setVariableDatumLength()) payloadList.add(newVariableDatum); diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttESPDUSender.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttESPDUSender.java index 02395f1f81c27890325b59e7dc5af8b99c32faf7..75912bbef4cbb96dd1b50431b08858a73b824bc4 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttESPDUSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttESPDUSender.java @@ -9,7 +9,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.*; import edu.nps.moves.dis7.enumerations.Country; import edu.nps.moves.dis7.enumerations.EntityKind; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttEspduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttEspduReceiver.java index 9343fb34e0c6c701fa376ae4dd0724bcdfe9abce..ef2c11e4e87e74722d0950bcfe3746b772178465 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttEspduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttEspduReceiver.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.*; /** diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttPDUSaverListener.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttPDUSaverListener.java index 32628ec6ac4e6f77be5ede876fd6638d1d241dd8..b4e9018c36866a4c67a4322d7ab2cdd28157954a 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttPDUSaverListener.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Schutt/SchuttPDUSaverListener.java @@ -4,7 +4,7 @@ * and open the template in the editor. */ package MV3500Cohort2019JulySeptember.homework4.Schutt; -import edu.nps.moves.dis7.util.playerrecorder.Recorder; +import edu.nps.moves.dis7.utilities.stream.PduRecorder; import java.io.IOException; import java.util.Scanner; @@ -53,7 +53,7 @@ public class SchuttPDUSaverListener System.out.println("Beginning pdu save to directory " + outDir); try { - Recorder recorder = new Recorder(outDir, mcast, port); + PduRecorder recorder = new PduRecorder(outDir, mcast, port); recorder.startResume(); mystate state = mystate.RUNNING; @@ -80,9 +80,9 @@ public class SchuttPDUSaverListener break; } } - System.out.println("Ending pdu save to "+recorder.getLogFile()); + System.out.println("Ending pdu save to "+recorder.getLogFilePath()); } - catch (IOException ex) { + catch (Exception ex) { System.err.println("*** Exception: " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage()); } } diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Yurkovich/Yurk_EspduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Yurkovich/Yurk_EspduReceiver.java index 6d7f7b6f1660b454ce60a5fc261079505ab19d5f..2783b68f3cdefe201ff525cc96f86036b7081b7c 100755 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Yurkovich/Yurk_EspduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Yurkovich/Yurk_EspduReceiver.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.*; /** diff --git a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Yurkovich/Yurk_EspduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Yurkovich/Yurk_EspduSender.java index 45d005b3af5f817fc4bee65d93eca8674545a44f..3cd8c5befe8559adbd79f8f16912760eed08ff26 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/homework4/Yurkovich/Yurk_EspduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/homework4/Yurkovich/Yurk_EspduSender.java @@ -4,11 +4,8 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.*; -import edu.nps.moves.dis7.enumerations.Country; -import edu.nps.moves.dis7.enumerations.EntityKind; -import edu.nps.moves.dis7.enumerations.PlatformDomain; /** * Creates and sends ESPDUs in IEEE binary format. Adapted from OpenDIS library diff --git a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC1_MCAST_PduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC1_MCAST_PduSender.java index 88b3e29bda4c83342d0022a74edd097bc74b1b64..95c656c68133d0aa58de0c8f6c92523070af6a8a 100755 --- a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC1_MCAST_PduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC1_MCAST_PduSender.java @@ -5,7 +5,7 @@ import java.io.*; import java.net.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import java.util.logging.Level; import java.util.logging.Logger; @@ -94,7 +94,7 @@ public class BRE_KNO_MCC_PC1_MCAST_PduSender for (int i = 0; i < numbOfPDUs; i++) { CommentPdu newCommentPdu = new CommentPdu(); - ArrayList<VariableDatum> payloadList = new ArrayList<VariableDatum>(); + ArrayList<VariableDatum> payloadList = new ArrayList<>(); ArrayList<String> commentsList = new ArrayList<>(); newCommentPdu.setTimestamp((intervall * 5) + i ); diff --git a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_Controller.java b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_Controller.java index e1fe5cbfe32afa4a5aad588a49ac44a028daea7c..90e79875842cbdf435f748687ed8a3f5fd1af035 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_Controller.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_Controller.java @@ -1,6 +1,6 @@ package MV3500Cohort2019JulySeptember.projects.BrennenstuhlKnobelochMcCann; -import edu.nps.moves.dis7.Pdu; +import edu.nps.moves.dis7.pdus.Pdu; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC1_MCAST_PduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC1_MCAST_PduReceiver.java index ee513e773015a1e0e8bcfbbe129fc76715e950c2..e36e82cc707088545c70f4532f965cf2f88898f9 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC1_MCAST_PduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC1_MCAST_PduReceiver.java @@ -6,7 +6,7 @@ import com.sun.corba.se.impl.orbutil.concurrent.Mutex; // JDK 8 import java.net.*; import java.io.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; import edu.nps.moves.dis7.utilities.*; import java.util.ArrayList; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC3_UNICAST_PduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC3_UNICAST_PduReceiver.java index a0dffe5c75e42284e0b4bcf856d652b118b2d92d..5022ef29afda27a5ec7b9988c0ab51cabef7a743 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC3_UNICAST_PduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC3_UNICAST_PduReceiver.java @@ -13,6 +13,7 @@ public class BRE_KNO_MCC_PC2_PC3_UNICAST_PduReceiver extends Thread static int portPC3; + @Override public void run() { isRunning = true; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC3_UNICAST_PduSender.java b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC3_UNICAST_PduSender.java index 87bc5b00219ba0bd3f18d45ec0556c5576490cb8..c69ab2a5ba32595c9ee1c0042fd3a4437a7bcd74 100755 --- a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC3_UNICAST_PduSender.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC2_PC3_UNICAST_PduSender.java @@ -5,7 +5,7 @@ import com.sun.corba.se.impl.orbutil.concurrent.Mutex; // JDK 8 // maybe https://crunchify.com/what-is-java-semaphore-and-mutex-java-concurrency-multithread-explained-with-example/ import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.DISPDUType; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; @@ -27,6 +27,7 @@ public class BRE_KNO_MCC_PC2_PC3_UNICAST_PduSender extends Thread static InetAddress pc3IP; static int portPC3; + @Override public void run() { try diff --git a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC3_PC2_UNICAST_PduReceiver.java b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC3_PC2_UNICAST_PduReceiver.java index de2f52bf8fd7472793f92314d95cc7e05434d448..7f17d59ebb9724a65938a1897231ce8ba829eb0d 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC3_PC2_UNICAST_PduReceiver.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/projects/BrennenstuhlKnobelochMcCann/BRE_KNO_MCC_PC3_PC2_UNICAST_PduReceiver.java @@ -3,8 +3,8 @@ package MV3500Cohort2019JulySeptember.projects.BrennenstuhlKnobelochMcCann; import java.net.*; import java.io.*; -import edu.nps.moves.dis7.*; -import edu.nps.moves.dis7.util.PduFactory; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.PduFactory; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; diff --git a/assignments/src/MV3500Cohort2019JulySeptember/projects/SchuttFetterolf/AllPduRoundTripTest.java b/assignments/src/MV3500Cohort2019JulySeptember/projects/SchuttFetterolf/AllPduRoundTripTest.java index a81eb73c898e08a5fa3ac4ac568b50239ce83c8f..4149955944923fb712b91ee9ccbcbd9860725766 100644 --- a/assignments/src/MV3500Cohort2019JulySeptember/projects/SchuttFetterolf/AllPduRoundTripTest.java +++ b/assignments/src/MV3500Cohort2019JulySeptember/projects/SchuttFetterolf/AllPduRoundTripTest.java @@ -22,7 +22,7 @@ //import com.google.common.io.Files; //import edu.nps.moves.dis7.enumerations.Country; //import edu.nps.moves.dis7.enumerations.DISPDUType; -//import edu.nps.moves.dis7.util.DisThreadedNetIF; +//import edu.nps.moves.dis7.util.DisThreadedNetworkInterface; //import edu.nps.moves.dis7.util.PduFactory; //import edu.nps.moves.dis7.util.playerrecorder.Player; //import edu.nps.moves.dis7.util.playerrecorder.Recorder; @@ -171,32 +171,32 @@ // private HashMap<DISPDUType, Pdu> pduReceivedMap = new HashMap<>(); // private HashMap<DISPDUType, Pdu> pduReadMap = new HashMap<>(); // -// DisThreadedNetIF disnetworking; +// DisThreadedNetworkInterface disNetworkInterface; // Recorder recorder; // // private void setupReceiver() // { -// disnetworking = new DisThreadedNetIF(); -// disnetworking.addListener(pdu -> { +// disNetworkInterface = new DisThreadedNetworkInterface(); +// disNetworkInterface.addListener(pdu -> { // pduReceivedMap.put(pdu.getPduType(), pdu); // }); // } // // private void shutDownReceiver() // { -// disnetworking.kill(); +// disNetworkInterface.kill(); // } // // private void sendOne(Pdu pdu) // { // pduSentMap.put(pdu.getPduType(), pdu); -// disnetworking.send(pdu); +// disNetworkInterface.send(pdu); // } // // private void setupRecorder() throws Exception // { // recorderDirectory = Files.createTempDir(); -// recorder = new Recorder(recorderDirectory.getAbsolutePath(), disnetworking.getMcastGroup(), disnetworking.getDisPort()); +// recorder = new Recorder(recorderDirectory.getAbsolutePath(), disNetworkInterface.getMcastGroup(), disNetworkInterface.getDisPort()); // System.out.println("Recorder log at " + recorderDirectory.getAbsolutePath()); // } // @@ -215,7 +215,7 @@ // private void getAllFromRecorder(Semaphore sem) throws Exception // { // sem.acquire(); -// Player player = new Player(disnetworking.getMcastGroup(), disnetworking.getDisPort(), recorderDirectory.toPath()); +// Player player = new Player(disNetworkInterface.getMcastGroup(), disNetworkInterface.getDisPort(), recorderDirectory.toPath()); // player.sendToNet(false); // player.addRawListener(ba -> { // if (ba != null) { diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/Output1Recieving Message.png b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/Output1Recieving Message.png new file mode 100644 index 0000000000000000000000000000000000000000..04a3d41a92c8a273bbac30434640d86dc667704d Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/Output1Recieving Message.png differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/Output2Recieving Message.png b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/Output2Recieving Message.png new file mode 100644 index 0000000000000000000000000000000000000000..787ffc0f8018c4dcd3ad5325bc7541834a750bad Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/Output2Recieving Message.png differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/OutputSender.png b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/OutputSender.png new file mode 100644 index 0000000000000000000000000000000000000000..adbd9692717ac602f0c10f58393359aacd21ea8f Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/OutputSender.png differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/UdpReceiver.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/UdpReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..cd1dfea7540df9ea87f7f3c9cf227af586f59ea1 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/UdpReceiver.java @@ -0,0 +1,92 @@ +package UdpMulticastExamples; + +import java.io.*; +import java.net.*; + +/** + * An example of receiving UDP packets. Since very often both the + * sender and receiver are on the same host we use different ports + * for each. This prevents collision complaints from the localhost. + * + * Start this before launching UdpSender. + * + * @see https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html + * @see https://en.wikipedia.org/wiki/User_Datagram_Protocol + * @author mcgredo + * @author brutzman + */ +public class UdpReceiver +{ +// public static final int SENDING_PORT = 1414; // port used by UdpSender, unneeded here + public static final int RECEIVING_PORT = 1415; + public static final String DESINATION_HOST = "localhost"; + + /** + * @param args the command line arguments + * @throws java.io.IOException + */ + public static void main(String[] args) throws IOException + { + DatagramSocket udpSocket = null; + + try + { + System.out.println(UdpReceiver.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(RECEIVING_PORT); + udpSocket.setReceiveBufferSize(1500); // how many bytes are in buffer? MTU=1500 is good + udpSocket.setBroadcast(false); // we're just receiving here + + byte[] byteArray = new byte[1500]; + DatagramPacket receivePacket = new DatagramPacket(byteArray, byteArray.length); + + ByteArrayInputStream bais = new ByteArrayInputStream(byteArray); + DataInputStream dis = new DataInputStream(bais); + + boolean isEvenParity; + int packetCount = 0; + int firstInt; + float secondFloat; + String thirdString; + String padding; + + // You need a new receiving packet to read from every packet received + while (true) + { + packetCount++; // good practice to increment counter at start of loop, when possible + udpSocket.receive(receivePacket); // blocks until packet is received + + // values of interest follow. order and types of what was sent must match what you are reading! + firstInt = dis.readInt(); // packetID + secondFloat = dis.readFloat(); + thirdString = dis.readUTF(); // string value with guaranteed encoding, matches UTF-8 is 8 bit + isEvenParity = dis.readBoolean(); // ok, we've gotten everything we're looking for. + + dis.reset(); // now clear the input stream after reading, in preparation for next loop + + if (isEvenParity) + padding = " "; + else padding = ""; + + System.out.println("[" + UdpReceiver.class.getName() + "]" + + " packetID=" + firstInt + // have output message use same name as sender + ", second float value=" + secondFloat + + ", third String value=\"" + thirdString + "\"" + // note that /" is literal quote character + " isPacketIdEvenParity=" + isEvenParity + "," + padding + + " packet counter=" + packetCount); + } + } + catch(IOException e) + { + System.err.println("Problem with UdpReceiver, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombie socket + { + if (udpSocket != null) + udpSocket.close(); + System.out.println(UdpReceiver.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/UdpSender.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/UdpSender.java new file mode 100644 index 0000000000000000000000000000000000000000..0e4dc8fee99195aeeee1a537be44a7b27c18e99a --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Britt/UdpSender.java @@ -0,0 +1,115 @@ +package UdpMulticastExamples; + +import java.io.*; +import java.net.*; + +/** + * An example of sending UDP packets. The sending and receiving programs + * use different UDP ports; there can be problems getting this to work + * if both the sending and receiving sockets try to use the same port + * on the same host. + * + * Start this before launching UdpReceiver. + * + * @see https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html + * @see https://en.wikipedia.org/wiki/User_Datagram_Protocol + * @author mcgredo + * @author brutzman + */ +public class UdpSender +{ + // System properties: https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html + public static final String MY_NAME = System.getProperty("user.name"); // guru incantation 8) +// public static final int SENDING_PORT = 1414; // not needed, can let system choose an open local port + public static final int RECEIVING_PORT = 1415; + public static final int TOTAL_PACKETS_TO_SEND = 100; + + // here is what we need for lab comms + public static final String DESTINATION_HOST = "10.1.105.16"; // localhost 127.0.0.1 or argon 10.1.105.1 or 10.1.105.1 or whatever + + @SuppressWarnings("SleepWhileInLoop") + public static void main(String[] args) throws IOException + { + DatagramSocket udpSocket = null; + DataOutputStream dos = null; + int packetID = 0; // counter variable to send in packet + float value = -1.0f; // unreachable value is good sentinel to ensure expected changes occur + String message = MY_NAME + " says We got London on da Track"; // no really + String padding = new String(); + + try + { + System.out.println(UdpSender.class.getName() + " shows how to send simple-type values via DataOutputStream"); + System.out.println(UdpSender.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(); // let system assign output port, then SENDING_PORT not needed + + // Put together a message with binary content. "ByteArrayOutputStream" + // is a java.io utility that lets us put together an array of binary + // data, which we put into the UDP packet. + + ByteArrayOutputStream baos = new ByteArrayOutputStream(1500); // how many bytes are in buffer? MTU=1500 is good + dos = new DataOutputStream(baos); // wrapper for writing values, connects both streams + + // Put together a packet to send + // these types and order of variables must match on sender and receiver + byte[] byteArray = baos.toByteArray(); + + // ID of the host we are sending to + InetAddress destinationAddress = InetAddress.getByName(DESTINATION_HOST); + // ID of the host we are sending from + InetAddress sourceAddress = InetAddress.getByName("localhost"); // possibly identical if source not modified + + DatagramPacket datagramPacket = new DatagramPacket(byteArray, byteArray.length, destinationAddress, RECEIVING_PORT); + + // Hmmm, how fast does UDP stream go? Does UDP effectively slow packets down, or does + // this cause network problems? (hint: yes for an unlimited send rate, unlike TCP). + // How do you know on the receiving side that you haven't received a + // duplicate UDP packet, out-of-order packet, or dropped packet? your responsibility. + + for (int index = 1; index <= TOTAL_PACKETS_TO_SEND; index++) // avoid infinite send loops in code, they can be hard to kill! + { + packetID++; // increment counter, prefer using explicit value to index + value = TOTAL_PACKETS_TO_SEND - packetID; // countdown + boolean isPacketIdEvenParity = ((packetID % 2) == 0); // % is modulo operator; result 0 is even parity, 1 is odd parity + + // values of interest follow. order and types of what was sent must match what you are reading! + dos.writeInt (packetID); + dos.writeFloat (value); + dos.writeUTF (message); // string value with guaranteed encoding, matches UTF-8 is 8 bit + dos.writeBoolean(isPacketIdEvenParity); + + dos.flush(); // sends DataOutputStream to ByteArrayOutputStream + byteArray = baos.toByteArray(); // OK so go get the flushed result... + datagramPacket.setData(byteArray); // and put it in the packet... + udpSocket.send(datagramPacket); // and send it away. boom gone, nonblocking. +// System.out.println("udpSocket output port=" + udpSocket.getLocalPort()); // diagnostic tells what port was chosen by system + + if (isPacketIdEvenParity) + padding = " "; + else padding = ""; + + Thread.sleep(1000); // Send packets at rate of one per second + System.out.println("[" + UdpSender.class.getName() + "] " + MY_NAME + " " + sourceAddress + + " sent values(" + packetID + "," + value + ",\"" + message + "\"," + isPacketIdEvenParity + + ")" + padding + " as packet #" + index + " of " + TOTAL_PACKETS_TO_SEND); + baos.reset(); // clear the output stream after sending + } + } + catch (IOException | InterruptedException e) + { + System.err.println("Problem with UdpSender, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombies + { + if (udpSocket != null) + udpSocket.close(); + + if (dos != null) + dos.close(); + System.out.println(UdpSender.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonReceivingSendingScreenshots.pdf b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonReceivingSendingScreenshots.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f8999ad7cd6af4f5270ed9c4c22962ae4057b5ea Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonReceivingSendingScreenshots.pdf differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonUdpReceiver.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonUdpReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..dfbb3430f83c30674323d55bd78a063562248eb2 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonUdpReceiver.java @@ -0,0 +1,92 @@ +package MV3500Cohort2020JulySeptember.homework3.Cannon; + +import java.io.*; +import java.net.*; + +/** + * An example of receiving UDP packets. Since very often both the + * sender and receiver are on the same host we use different ports + * for each. This prevents collision complaints from the localhost. + * + * Start this before launching UdpSender. + * + * @see https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html + * @see https://en.wikipedia.org/wiki/User_Datagram_Protocol + * @author mcgredo + * @author brutzman + */ +public class CannonUdpReceiver +{ +// public static final int SENDING_PORT = 1414; // port used by UdpSender, unneeded here + public static final int RECEIVING_PORT = 1415; + public static final String DESINATION_HOST = "localhost"; + + /** + * @param args the command line arguments + * @throws java.io.IOException + */ + public static void main(String[] args) throws IOException + { + DatagramSocket udpSocket = null; + + try + { + System.out.println(CannonUdpReceiver.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(RECEIVING_PORT); + udpSocket.setReceiveBufferSize(1500); // how many bytes are in buffer? MTU=1500 is good + udpSocket.setBroadcast(false); // we're just receiving here + + byte[] byteArray = new byte[1500]; + DatagramPacket receivePacket = new DatagramPacket(byteArray, byteArray.length); + + ByteArrayInputStream bais = new ByteArrayInputStream(byteArray); + DataInputStream dis = new DataInputStream(bais); + + boolean isEvenParity; + int packetCount = 0; + int firstInt; + float secondFloat; + String thirdString; + String padding; + + // You need a new receiving packet to read from every packet received + while (true) + { + packetCount++; // good practice to increment counter at start of loop, when possible + udpSocket.receive(receivePacket); // blocks until packet is received + + // values of interest follow. order and types of what was sent must match what you are reading! + firstInt = dis.readInt(); // packetID + secondFloat = dis.readFloat(); + thirdString = dis.readUTF(); // string value with guaranteed encoding, matches UTF-8 is 8 bit + isEvenParity = dis.readBoolean(); // ok, we've gotten everything we're looking for. + + dis.reset(); // now clear the input stream after reading, in preparation for next loop + + if (isEvenParity) + padding = " "; + else padding = ""; + + System.out.println("[" + CannonUdpReceiver.class.getName() + "]" + + " packetID=" + firstInt + // have output message use same name as sender + ", second float value=" + secondFloat + + ", third String value=\"" + thirdString + "\"" + // note that /" is literal quote character + " isPacketIdEvenParity=" + isEvenParity + "," + padding + + " packet counter=" + packetCount); + } + } + catch(IOException e) + { + System.err.println("Problem with UdpReceiver, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombie socket + { + if (udpSocket != null) + udpSocket.close(); + System.out.println(CannonUdpReceiver.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonUdpSender.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonUdpSender.java new file mode 100644 index 0000000000000000000000000000000000000000..471f5e0c49b35e0b6ca23906e218d26faf2b6ce9 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Cannon/CannonUdpSender.java @@ -0,0 +1,115 @@ +package MV3500Cohort2020JulySeptember.homework3.Cannon; + +import java.io.*; +import java.net.*; + +/** + * An example of sending UDP packets. The sending and receiving programs + * use different UDP ports; there can be problems getting this to work + * if both the sending and receiving sockets try to use the same port + * on the same host. + * + * Start this before launching UdpReceiver. + * + * @see https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html + * @see https://en.wikipedia.org/wiki/User_Datagram_Protocol + * @author mcgredo + * @author brutzman + */ +public class CannonUdpSender +{ + // System properties: https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html + public static final String MY_NAME = System.getProperty("user.name"); // guru incantation 8) +// public static final int SENDING_PORT = 1414; // not needed, can let system choose an open local port + public static final int RECEIVING_PORT = 1415; + public static final int TOTAL_PACKETS_TO_SEND = 100; + + // here is what we need for lab comms + public static final String DESTINATION_HOST = "10.1.105.7"; // localhost 127.0.0.1 or argon 10.1.105.1 or 10.1.105.1 or whatever + + @SuppressWarnings("SleepWhileInLoop") + public static void main(String[] args) throws IOException + { + DatagramSocket udpSocket = null; + DataOutputStream dos = null; + int packetID = 0; // counter variable to send in packet + float value = -1.0f; // unreachable value is good sentinel to ensure expected changes occur + String message = MY_NAME + " says we need to understand llamas in order to code"; // no really + String padding = new String(); + + try + { + System.out.println(CannonUdpSender.class.getName() + " shows how to send simple-type values via DataOutputStream"); + System.out.println(CannonUdpSender.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(); // let system assign output port, then SENDING_PORT not needed + + // Put together a message with binary content. "ByteArrayOutputStream" + // is a java.io utility that lets us put together an array of binary + // data, which we put into the UDP packet. + + ByteArrayOutputStream baos = new ByteArrayOutputStream(1500); // how many bytes are in buffer? MTU=1500 is good + dos = new DataOutputStream(baos); // wrapper for writing values, connects both streams + + // Put together a packet to send + // these types and order of variables must match on sender and receiver + byte[] byteArray = baos.toByteArray(); + + // ID of the host we are sending to + InetAddress destinationAddress = InetAddress.getByName(DESTINATION_HOST); + // ID of the host we are sending from + InetAddress sourceAddress = InetAddress.getByName("localhost"); // possibly identical if source not modified + + DatagramPacket datagramPacket = new DatagramPacket(byteArray, byteArray.length, destinationAddress, RECEIVING_PORT); + + // Hmmm, how fast does UDP stream go? Does UDP effectively slow packets down, or does + // this cause network problems? (hint: yes for an unlimited send rate, unlike TCP). + // How do you know on the receiving side that you haven't received a + // duplicate UDP packet, out-of-order packet, or dropped packet? your responsibility. + + for (int index = 1; index <= TOTAL_PACKETS_TO_SEND; index++) // avoid infinite send loops in code, they can be hard to kill! + { + packetID++; // increment counter, prefer using explicit value to index + value = TOTAL_PACKETS_TO_SEND - packetID; // countdown + boolean isPacketIdEvenParity = ((packetID % 2) == 0); // % is modulo operator; result 0 is even parity, 1 is odd parity + + // values of interest follow. order and types of what was sent must match what you are reading! + dos.writeInt (packetID); + dos.writeFloat (value); + dos.writeUTF (message); // string value with guaranteed encoding, matches UTF-8 is 8 bit + dos.writeBoolean(isPacketIdEvenParity); + + dos.flush(); // sends DataOutputStream to ByteArrayOutputStream + byteArray = baos.toByteArray(); // OK so go get the flushed result... + datagramPacket.setData(byteArray); // and put it in the packet... + udpSocket.send(datagramPacket); // and send it away. boom gone, nonblocking. +// System.out.println("udpSocket output port=" + udpSocket.getLocalPort()); // diagnostic tells what port was chosen by system + + if (isPacketIdEvenParity) + padding = " "; + else padding = ""; + + Thread.sleep(1000); // Send packets at rate of one per second + System.out.println("[" + CannonUdpSender.class.getName() + "] " + MY_NAME + " " + sourceAddress + + " sent values(" + packetID + "," + value + ",\"" + message + "\"," + isPacketIdEvenParity + + ")" + padding + " as packet #" + index + " of " + TOTAL_PACKETS_TO_SEND); + baos.reset(); // clear the output stream after sending + } + } + catch (IOException | InterruptedException e) + { + System.err.println("Problem with UdpSender, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombies + { + if (udpSocket != null) + udpSocket.close(); + + if (dos != null) + dos.close(); + System.out.println(CannonUdpSender.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/Garibay_Receiving_Message_Screenshot.png b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/Garibay_Receiving_Message_Screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..cbb912bab6c489924bd319693efa221e551c5fcc Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/Garibay_Receiving_Message_Screenshot.png differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/Garibay_Sending_Message_Screenshot.png b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/Garibay_Sending_Message_Screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..b92d41084c8cc01b4fce816f91a2e5d1d2cfb467 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/Garibay_Sending_Message_Screenshot.png differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/UDPReceiverGaribay.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/UDPReceiverGaribay.java index 2f1b250b8d9b45e30625ddfc4de3c28441861ba4..29a74cea5ae6d55fbde366c3b31d7ab288e1bff6 100644 --- a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/UDPReceiverGaribay.java +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/UDPReceiverGaribay.java @@ -27,7 +27,7 @@ public class UDPReceiverGaribay try { - System.out.println(UdpReceiver.class.getName() + " started..."); + System.out.println(UDPReceiverGaribay.class.getName() + " started..."); // Create a UDP socket udpSocket = new DatagramSocket(RECEIVING_PORT); @@ -65,7 +65,7 @@ public class UDPReceiverGaribay padding = " "; else padding = ""; - System.out.println("[" + UdpReceiver.class.getName() + "]" + + System.out.println("[" + UDPReceiverGaribay.class.getName() + "]" + " packetID=" + firstInt + // have output message use same name as sender ", second float value=" + secondFloat + ", third String value=\"" + thirdString + "\"" + // note that /" is literal quote character @@ -82,7 +82,7 @@ public class UDPReceiverGaribay { if (udpSocket != null) udpSocket.close(); - System.out.println(UdpReceiver.class.getName() + " complete."); // all done + System.out.println(UDPReceiverGaribay.class.getName() + " complete."); // all done } } } diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/UDPSenderGaribay.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/UDPSenderGaribay.java index 21c6de803955c64d7ea0a8d431185b524e839733..8d6a81c06dd090f9d281f90818551cfed1c50a11 100644 --- a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/UDPSenderGaribay.java +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Garibay/UDPSenderGaribay.java @@ -1,9 +1,7 @@ package MV3500Cohort2020JulySeptember.homework3.Garibay; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.DatagramPacket; @@ -38,8 +36,8 @@ public class UDPSenderGaribay try { - System.out.println(UdpSender.class.getName() + " shows how to send simple-type values via DataOutputStream"); - System.out.println(UdpSender.class.getName() + " started..."); + System.out.println(UDPSenderGaribay.class.getName() + " shows how to send simple-type values via DataOutputStream"); + System.out.println(UDPSenderGaribay.class.getName() + " started..."); // Create a UDP socket udpSocket = new DatagramSocket(); // let system assign output port, then SENDING_PORT not needed @@ -90,7 +88,7 @@ public class UDPSenderGaribay else padding = ""; Thread.sleep(1000); // Send packets at rate of one per second - System.out.println("[" + UdpSender.class.getName() + "] " + MY_NAME + " " + sourceAddress + + System.out.println("[" + UDPSenderGaribay.class.getName() + "] " + MY_NAME + " " + sourceAddress + " sent values(" + packetID + "," + value + ",\"" + message + "\"," + isPacketIdEvenParity + ")" + padding + " as packet #" + index + " of " + TOTAL_PACKETS_TO_SEND); baos.reset(); // clear the output stream after sending @@ -98,7 +96,7 @@ public class UDPSenderGaribay } catch (IOException | InterruptedException e) { - System.err.println("Problem with UdpSender, see exception trace:"); + System.err.println("Problem with UDPSenderGaribay, see exception trace:"); System.err.println(e); } finally // clean up prior to exit, don't want to leave behind zombies @@ -108,7 +106,7 @@ public class UDPSenderGaribay if (dos != null) dos.close(); - System.out.println(UdpSender.class.getName() + " complete."); // all done + System.out.println(UDPSenderGaribay.class.getName() + " complete."); // all done } } } diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Mahan/README.md b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Mahan/README.md index 0144d62d033fbe094ceac7a6d1bedc12d3c158b0..40200564c63ff03aa0328e08b2713cd80d252c3a 100644 --- a/assignments/src/MV3500Cohort2020JulySeptember/homework3/Mahan/README.md +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/Mahan/README.md @@ -1,12 +1,8 @@ -## Homework 2: Multicast Networking -Modify this file to describe your project work. +This program uses UDP over ARGON.net +to connect with Chris Garibay's port and then +finds the modulo as being either true or false. +Just run the server and the corresponding receiver. +Also included are two screenshots to verify +send and receive capabilities. -Typical deliverables include properly packages source, execution log, and screen shots as appropriate. - -References include -* [README.md](../README.md) for this homework project. -* [README.md](../../../../README.md) for course assignments execution instructions. -* [assignments source subdirectories](../../../../../assignments/src) show examples from previous cohorts. - -Questions and innovation are always welcome, good luck! diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/README.md b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3ec21e2b976a5937ab94a80cb4028ccb79441eae --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/README.md @@ -0,0 +1,39 @@ +## Homework 2: Multicast Networking + +Modify this file to describe your project work. + +Typical deliverables include properly packages source, execution log, and screen shots as appropriate. + +References include +* [README.md](../README.md) for this homework project. +* [README.md](../../../../README.md) for course assignments execution instructions. +* [assignments source subdirectories](../../../../../assignments/src) show examples from previous cohorts. + +Questions and innovation are always welcome, good luck! + + + +************************************************** +Project for HW #3 +Team: "Germany" (Stefan and Bernd) +************************************************** + + + +This program(s) do(es) the following: +- send two numbers, a mathematical operator and a port number over VPN to a TCP receiver +- the TCP receiver calculates the result and send it back to the sender over VPN using UDP! +- the UDP receiver shows the result + +The main focus was to send via TCP over a VPN, do something and send the result back via UDP. + +How to run the project: +0. connect both computer with the argon net +1. run UDPResultReceiver on Bernd's computer +2. run TCPNumberReceiverUDPResultSender on Stefan's computer +3. find Stefan's IP within the argon net +4. change the TCP_ARGON_SERVER_IP in class TCPNumberSender to Stefan's IP. +5. run TCPNumberSender + +(you can edit the numbers and run TCPNumberSender multiple times...) + diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/Screenshots.docx b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/Screenshots.docx new file mode 100644 index 0000000000000000000000000000000000000000..ccb72d8a6b6bf96522119ec8837209f50fba9496 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/Screenshots.docx differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/TCPNumberReceiverUDPResultSender.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/TCPNumberReceiverUDPResultSender.java new file mode 100644 index 0000000000000000000000000000000000000000..14ac299c8a175857436a6989babc2a83a7575896 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/TCPNumberReceiverUDPResultSender.java @@ -0,0 +1,176 @@ +package MV3500Cohort2020JulySeptember.homework3.WeissenbergerGoericke; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * This class will be connected by an TCP sender over VPN (argon), calculating + * a result of an equation and send the result back via UDP over VPN. + * @date 08/17/2020 + * @group Goericke/Weissenberger + */ +public class TCPNumberReceiverUDPResultSender { + + // Change this to the port where the TCP server is listening + private static final int TCP_ARGON_SERVER_PORT = 2317; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + try { + + // ServerSocket waits for a connection from a client. + System.out.println("TCPNumberReceiver has started..."); + ServerSocket serverSocket = new ServerSocket(TCP_ARGON_SERVER_PORT); + InetAddress remoteAddress; + + // declare the stream and readers + InputStream inputStream; + InputStreamReader inputStreamReader; + BufferedReader bufferedReader; + + // declare needed variables + String clientMessage; + int number1, number2; + String calculation_Method; + int iUDPResultReceivingPort; + // Server is up and waiting (i.e. "blocked" or paused) + // Loop, infinitely, waiting for client connections. + while (true) { + + // block until connected to a client + try (Socket clientConnectionSocket = serverSocket.accept()) + { + // Now hook everything up (i.e. set up the streams), Java style: + inputStream = clientConnectionSocket.getInputStream(); + inputStreamReader = new InputStreamReader(inputStream); + bufferedReader = new BufferedReader(inputStreamReader); + + // get the date from TCP packet + clientMessage = bufferedReader.readLine(); + number1 = Integer.parseInt(bufferedReader.readLine()); + number2 = Integer.parseInt(bufferedReader.readLine()); + calculation_Method = bufferedReader.readLine(); + iUDPResultReceivingPort = Integer.parseInt(bufferedReader.readLine()); + + // print them out (for debugging) + System.out.println("Message recived: "+clientMessage); + System.out.println("Number 1 recived: "+number1); + System.out.println("Number 2 recived: "+number2); + System.out.println("Calc Method recived: "+calculation_Method); + System.out.println("Send result to port: "+iUDPResultReceivingPort); + // get the sender IP (is used for sending UDP) + remoteAddress = clientConnectionSocket.getInetAddress(); + + System.out.println("Send result to IP: "+remoteAddress.getHostAddress()); + + // try to send the calculated result as a float via UDP... + sendResultViaUDP(calculateResult(number1, number2, calculation_Method), remoteAddress, iUDPResultReceivingPort); + } + } + } catch (IOException e) { + System.err.println("Problem with TcpExample3Server networking: " + e); + + // Provide more helpful information to user if exception occurs due to running twice at one time + if (e instanceof java.net.BindException) { + System.err.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } + } + + /** + * send the result to Bernd 10x + * @param result + * @param inetAddress Bernd's IP + * @param port Bernd's UDP port number + * @throws IOException + */ + private static void sendResultViaUDP(float result, InetAddress inetAddress, int port) throws IOException{ + DatagramSocket udpSocket = null; + DataOutputStream dos = null; + + try + { + // Create a UDP socket + udpSocket = new DatagramSocket(); // let system assign output port, then SENDING_PORT not needed + + // Put together a message with binary content. "ByteArrayOutputStream" + // is a java.io utility that lets us put together an array of binary + // data, which we put into the UDP packet. + + ByteArrayOutputStream baos = new ByteArrayOutputStream(1500); // how many bytes are in buffer? MTU=1500 is good + dos = new DataOutputStream(baos); // wrapper for writing values, connects both streams + + // Put together a packet to send + // these types and order of variables must match on sender and receiver + byte[] byteArray = baos.toByteArray(); + + DatagramPacket datagramPacket = new DatagramPacket(byteArray, byteArray.length, inetAddress, port); + + for (int index = 1; index <= 10; index++) + { + dos.writeFloat (result); + dos.flush(); // sends DataOutputStream to ByteArrayOutputStream + byteArray = baos.toByteArray(); // OK so go get the flushed result... + datagramPacket.setData(byteArray); // and put it in the packet... + udpSocket.send(datagramPacket); // and send it away. boom gone, nonblocking. + + Thread.sleep(1000); // Send packets at rate of one per second + baos.reset(); // clear the output stream after sending + } + dos.close(); + } + catch (IOException | InterruptedException e) + { + System.err.println("Problem with UdpSender, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombies + { + if (udpSocket != null) + udpSocket.close(); + + if (dos != null) + dos.close(); + } + } + + /** + * calculates the result based on given numbers and operator + * @param n1 first number + * @param n2 second number + * @param operator + * @return the result as a float + */ + private static float calculateResult(int n1, int n2, String operator){ + float result = -1; + switch (operator) { + case "+": + result = n1 + n2; + break; + case "-": + result = n1 - n2; + break; + case "*": + result = n1 * n2; + break; + case "/": + result = n1 / n2; + break; + default: + System.err.println(operator +" is not a valid operator!"); + break; + } + return result; + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/TCPNumberSender.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/TCPNumberSender.java new file mode 100644 index 0000000000000000000000000000000000000000..b84a10f1b7da60f66fd938f4aafce52f684ba3d8 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/TCPNumberSender.java @@ -0,0 +1,97 @@ + +package MV3500Cohort2020JulySeptember.homework3.WeissenbergerGoericke; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.Socket; + +/** + * This class will connect to an TCP receiver over VPN (argon) and send + * two numbers + * @date 08/17/2020 + * @author Loki + * @group Weissenberger/Goericke + */ +public class TCPNumberSender { + + // Change this to the IP address of the TCP server 10.1.105.10 (127.0.0.1 just for testing) + private static final String TCP_ARGON_SERVER_IP = "10.1.105.10"; + // Change this to the port where the TCP server is listening + private static final int TCP_ARGON_SERVER_PORT = 2317; + // Where the result should be posted (port) + private static final int UDP_ARGON_RECEIVING_PORT = 1415; + + private static final int NUMBER1 = 16; + private static final int NUMBER2 = 2; + private static final String CALCULATION_METHOD = "-"; + + // how many times should the number being sent + private static final int REPETITION = 1; + private static int counter = 0; + + public static void main(String[] args) throws InterruptedException { + + // Local variables + Socket socket; + OutputStream outputStream; + PrintStream printStream; + + try { + while (counter < REPETITION){ + // increment the counter + counter++; + System.out.println("Homwork 3: TcpNumberSender creating socket over VPN..."); + + // We request an IP to connect to "TCP_ARGON_SERVER_IP" over + // the argon VPN and port number at that IP "TCP_ARGON_SERVER_PORT". + // This establishes a connection to that IP in the form of a Socket + // object. + socket = new Socket(TCP_ARGON_SERVER_IP, TCP_ARGON_SERVER_PORT); // locohost? + + + // instanciate the streams: + outputStream = socket.getOutputStream(); + printStream = new PrintStream(outputStream); + // send a first text to server + printStream.println("This is message from client."); + printStream.flush(); + // wait 1 second + Thread.sleep(1000); + + // sending number 1 + printStream.println(NUMBER1); + // sending number 2 + printStream.println(NUMBER2); + // sending calc method + printStream.println(CALCULATION_METHOD); + // sending the port where the result should be send to + printStream.println(UDP_ARGON_RECEIVING_PORT); + printStream.flush(); + // wait 1 second + Thread.sleep(1000); + + System.out.println("=================================================="); + System.out.println(NUMBER1+" and "+NUMBER2+" were sent to server. Calculating method was: "+CALCULATION_METHOD); + + // close TCP socket to server + socket.close(); + } // end while(true) + } + catch (IOException e) + { + System.err.println("Problem with TCPNumberSender networking:"); + System.err.println("Error: " + e); + + if (e instanceof java.net.BindException) { + System.err.println("*** Be sure to stop any other running instances of programs using this port: "+TCP_ARGON_SERVER_PORT); + } + } + finally // occurs after any other activity when shutting down + { + System.out.println(); + System.out.println("TCPNumberSender exit"); + } + } + +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/UDPResultReceiver.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/UDPResultReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..1a181820810e24c66cfc6465fdb58824fad30e74 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/UDPResultReceiver.java @@ -0,0 +1,71 @@ + +package MV3500Cohort2020JulySeptember.homework3.WeissenbergerGoericke; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; + +/** + * This class will be connected by an UDP sender over VPN (argon) + * @date 08/17/2020 + * @author Loki + * @group Weissenberger/Goericke + */ +public class UDPResultReceiver { + + public static final int RECEIVING_PORT = 1415; + + /** + * @param args the command line arguments + * @throws java.io.IOException + */ + public static void main(String[] args) throws IOException + { + DatagramSocket udpSocket = null; + + try + { + System.out.println(UDPResultReceiver.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(RECEIVING_PORT); + udpSocket.setReceiveBufferSize(1500); // how many bytes are in buffer? MTU=1500 is good + udpSocket.setBroadcast(false); // we're just receiving here + + byte[] byteArray = new byte[1500]; + DatagramPacket receivePacket = new DatagramPacket(byteArray, byteArray.length); + + ByteArrayInputStream bais = new ByteArrayInputStream(byteArray); + DataInputStream dis = new DataInputStream(bais); + + float result; + + // You need a new receiving packet to read from every packet received + while (true) + { + udpSocket.receive(receivePacket); // blocks until packet is received + + result = dis.readFloat(); + + dis.reset(); // now clear the input stream after reading, in preparation for next loop + + System.out.println("Calculated result: "+result); + + } + } + catch(IOException e) + { + System.err.println("Problem with UdpReceiver, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombie socket + { + if (udpSocket != null) + udpSocket.close(); + System.out.println(UDPResultReceiver.class.getName() + " complete."); // all done + } + } + +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/logic.jpg b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/logic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5fa827094c869ea38ad6d265395843694f0263b8 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/logic.jpg differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/logic.vsdx b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/logic.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..4d2e6878bd82a1d201bc8f4742ff1a67d4cc5f34 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/logic.vsdx differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/sequence.jpg b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/sequence.jpg new file mode 100644 index 0000000000000000000000000000000000000000..44faf01bb3a35a5d7072c8705529f2ef73deecd7 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/sequence.jpg differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/sequence.vsdx b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/sequence.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..c43b2fe02d509af09eead57cd0180a2e5d5f1567 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework3/WeissenbergerGoericke/sequence.vsdx differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpReceiver.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..3038d6c38f4dd72197269901ef2ba8e65fef339f --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpReceiver.java @@ -0,0 +1,92 @@ +package MV3500Cohort2020JulySeptember.homework3.White; + +import java.io.*; +import java.net.*; + +/** + * An example of receiving UDP packets. Since very often both the + * sender and receiver are on the same host we use different ports + * for each. This prevents collision complaints from the localhost. + * + * Start this before launching UdpSender. + * + * @see https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html + * @see https://en.wikipedia.org/wiki/User_Datagram_Protocol + * @author mcgredo + * @author brutzman + */ +public class UdpReceiver +{ +// public static final int SENDING_PORT = 1414; // port used by UdpSender, unneeded here + public static final int RECEIVING_PORT = 1415; + public static final String DESINATION_HOST = "localhost"; + + /** + * @param args the command line arguments + * @throws java.io.IOException + */ + public static void main(String[] args) throws IOException + { + DatagramSocket udpSocket = null; + + try + { + System.out.println(UdpReceiver.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(RECEIVING_PORT); + udpSocket.setReceiveBufferSize(1500); // how many bytes are in buffer? MTU=1500 is good + udpSocket.setBroadcast(false); // we're just receiving here + + byte[] byteArray = new byte[1500]; + DatagramPacket receivePacket = new DatagramPacket(byteArray, byteArray.length); + + ByteArrayInputStream bais = new ByteArrayInputStream(byteArray); + DataInputStream dis = new DataInputStream(bais); + + boolean isEvenParity; + int packetCount = 0; + int firstInt; + float secondFloat; + String thirdString; + String padding; + + // You need a new receiving packet to read from every packet received + while (true) + { + packetCount++; // good practice to increment counter at start of loop, when possible + udpSocket.receive(receivePacket); // blocks until packet is received + + // values of interest follow. order and types of what was sent must match what you are reading! + firstInt = dis.readInt(); // packetID + secondFloat = dis.readFloat(); + thirdString = dis.readUTF(); // string value with guaranteed encoding, matches UTF-8 is 8 bit + isEvenParity = dis.readBoolean(); // ok, we've gotten everything we're looking for. + + dis.reset(); // now clear the input stream after reading, in preparation for next loop + + if (isEvenParity) + padding = " "; + else padding = ""; + + System.out.println("[" + UdpReceiver.class.getName() + "]" + + " packetID=" + firstInt + // have output message use same name as sender + ", second float value=" + secondFloat + + ", third String value=\"" + thirdString + "\"" + // note that /" is literal quote character + " isPacketIdEvenParity=" + isEvenParity + "," + padding + + " packet counter=" + packetCount); + } + } + catch(IOException e) + { + System.err.println("Problem with UdpReceiver, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombie socket + { + if (udpSocket != null) + udpSocket.close(); + System.out.println(UdpReceiver.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpRecieverLog.md b/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpRecieverLog.md new file mode 100644 index 0000000000000000000000000000000000000000..e7ebae81c9dc96f47e8fd850af64785deb81303b --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpRecieverLog.md @@ -0,0 +1,88 @@ +ant -f C:\\Users\\ctsfi\\Documents\\NetBeansProjects\\MV3500\\NetworkedGraphicsMV3500\\assignments -Dnb.internal.action.name=run.single -Djavac.includes=MV3500Cohort2020JulySeptember/homework3/White/UdpReceiver.java -Drun.class=MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver run-single +init: +Deleting: C:\Users\ctsfi\Documents\NetBeansProjects\MV3500\NetworkedGraphicsMV3500\assignments\build\built-jar.properties +deps-jar: +Updating property file: C:\Users\ctsfi\Documents\NetBeansProjects\MV3500\NetworkedGraphicsMV3500\assignments\build\built-jar.properties +Compiling 1 source file to C:\Users\ctsfi\Documents\NetBeansProjects\MV3500\NetworkedGraphicsMV3500\assignments\build\classes +warning: [options] bootstrap class path not set in conjunction with -source 8 +1 warning +compile-single: +run-single: +MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver started... +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=1, second float value=9999.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=1 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=2, second float value=9998.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=2 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=3, second float value=9997.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=3 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=4, second float value=9996.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=4 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=5, second float value=9995.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=5 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=6, second float value=9994.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=6 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=7, second float value=9993.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=7 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=8, second float value=9992.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=8 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=9, second float value=9991.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=9 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=10, second float value=9990.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=10 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=11, second float value=9989.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=11 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=12, second float value=9988.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=12 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=13, second float value=9987.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=13 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=14, second float value=9986.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=14 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=15, second float value=9985.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=15 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=16, second float value=9984.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=16 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=1, second float value=99.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=17 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=17, second float value=9983.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=18 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=2, second float value=98.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=19 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=18, second float value=9982.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=20 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=3, second float value=97.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=21 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=19, second float value=9981.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=22 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=4, second float value=96.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=23 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=20, second float value=9980.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=24 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=5, second float value=95.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=25 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=21, second float value=9979.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=26 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=6, second float value=94.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=27 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=22, second float value=9978.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=28 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=7, second float value=93.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=29 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=23, second float value=9977.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=30 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=8, second float value=92.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=31 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=24, second float value=9976.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=32 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=9, second float value=91.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=33 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=25, second float value=9975.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=34 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=10, second float value=90.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=35 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=26, second float value=9974.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=36 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=11, second float value=89.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=37 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=27, second float value=9973.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=38 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=12, second float value=88.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=39 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=28, second float value=9972.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=40 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=13, second float value=87.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=41 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=29, second float value=9971.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=42 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=14, second float value=86.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=43 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=30, second float value=9970.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=44 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=15, second float value=85.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=45 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=31, second float value=9969.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=46 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=16, second float value=84.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=47 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=32, second float value=9968.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=48 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=17, second float value=83.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=49 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=33, second float value=9967.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=50 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=18, second float value=82.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=51 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=34, second float value=9966.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=52 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=19, second float value=81.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=53 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=35, second float value=9965.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=54 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=20, second float value=80.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=55 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=36, second float value=9964.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=56 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=21, second float value=79.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=57 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=1, second float value=99.0, third String value="We got London on da Track" isPacketIdEvenParity=false, packet counter=58 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=37, second float value=9963.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=59 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=22, second float value=78.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=60 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=2, second float value=98.0, third String value="We got London on da Track" isPacketIdEvenParity=true, packet counter=61 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=38, second float value=9962.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=62 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=23, second float value=77.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=63 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=3, second float value=97.0, third String value="We got London on da Track" isPacketIdEvenParity=false, packet counter=64 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=39, second float value=9961.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=65 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=24, second float value=76.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=66 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=4, second float value=96.0, third String value="We got London on da Track" isPacketIdEvenParity=true, packet counter=67 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=40, second float value=9960.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=68 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=25, second float value=75.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=69 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=5, second float value=95.0, third String value="We got London on da Track" isPacketIdEvenParity=false, packet counter=70 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=41, second float value=9959.0, third String value="42 is the answer" isPacketIdEvenParity=false, packet counter=71 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=26, second float value=74.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=true, packet counter=72 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=6, second float value=94.0, third String value="We got London on da Track" isPacketIdEvenParity=true, packet counter=73 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=42, second float value=9958.0, third String value="42 is the answer" isPacketIdEvenParity=true, packet counter=74 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=27, second float value=73.0, third String value="chris says we need to understand llamas in order to code" isPacketIdEvenParity=false, packet counter=75 +[MV3500Cohort2020JulySeptember.homework3.White.UdpReceiver] packetID=7, second float value=93.0, third String value="We got London on da Track" isPacketIdEvenParity=false, packet counter=76 +BUILD STOPPED (total time: 59 seconds) diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpSender.java b/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpSender.java new file mode 100644 index 0000000000000000000000000000000000000000..d22d843330bf01b15fe4fd6edacbfea592ececc6 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework3/White/UdpSender.java @@ -0,0 +1,115 @@ +package MV3500Cohort2020JulySeptember.homework3.White; + +import java.io.*; +import java.net.*; + +/** + * An example of sending UDP packets. The sending and receiving programs + * use different UDP ports; there can be problems getting this to work + * if both the sending and receiving sockets try to use the same port + * on the same host. + * + * Start this before launching UdpReceiver. + * + * @see https://docs.oracle.com/javase/tutorial/essential/io/datastreams.html + * @see https://en.wikipedia.org/wiki/User_Datagram_Protocol + * @author mcgredo + * @author brutzman + */ +public class UdpSender +{ + // System properties: https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html + public static final String MY_NAME = "Alex"; // guru incantation 8) +// public static final int SENDING_PORT = 1414; // not needed, can let system choose an open local port + public static final int RECEIVING_PORT = 1415; + public static final int TOTAL_PACKETS_TO_SEND = 100; + + // here is what we need for lab comms + public static final String DESTINATION_HOST = "10.1.105.8"; // localhost 127.0.0.1 or argon 10.1.105.1 or 10.1.105.1 or whatever + + @SuppressWarnings("SleepWhileInLoop") + public static void main(String[] args) throws IOException + { + DatagramSocket udpSocket = null; + DataOutputStream dos = null; + int packetID = 0; // counter variable to send in packet + float value = -1.0f; // unreachable value is good sentinel to ensure expected changes occur + String message = MY_NAME + " says Fuck You, Pay Me"; // no really + String padding = new String(); + + try + { + System.out.println(UdpSender.class.getName() + " shows how to send simple-type values via DataOutputStream"); + System.out.println(UdpSender.class.getName() + " started..."); + + // Create a UDP socket + udpSocket = new DatagramSocket(); // let system assign output port, then SENDING_PORT not needed + + // Put together a message with binary content. "ByteArrayOutputStream" + // is a java.io utility that lets us put together an array of binary + // data, which we put into the UDP packet. + + ByteArrayOutputStream baos = new ByteArrayOutputStream(1500); // how many bytes are in buffer? MTU=1500 is good + dos = new DataOutputStream(baos); // wrapper for writing values, connects both streams + + // Put together a packet to send + // these types and order of variables must match on sender and receiver + byte[] byteArray = baos.toByteArray(); + + // ID of the host we are sending to + InetAddress destinationAddress = InetAddress.getByName(DESTINATION_HOST); + // ID of the host we are sending from + InetAddress sourceAddress = InetAddress.getByName("localhost"); // possibly identical if source not modified + + DatagramPacket datagramPacket = new DatagramPacket(byteArray, byteArray.length, destinationAddress, RECEIVING_PORT); + + // Hmmm, how fast does UDP stream go? Does UDP effectively slow packets down, or does + // this cause network problems? (hint: yes for an unlimited send rate, unlike TCP). + // How do you know on the receiving side that you haven't received a + // duplicate UDP packet, out-of-order packet, or dropped packet? your responsibility. + + for (int index = 1; index <= TOTAL_PACKETS_TO_SEND; index++) // avoid infinite send loops in code, they can be hard to kill! + { + packetID++; // increment counter, prefer using explicit value to index + value = TOTAL_PACKETS_TO_SEND - packetID; // countdown + boolean isPacketIdEvenParity = ((packetID % 2) == 0); // % is modulo operator; result 0 is even parity, 1 is odd parity + + // values of interest follow. order and types of what was sent must match what you are reading! + dos.writeInt (packetID); + dos.writeFloat (value); + dos.writeUTF (message); // string value with guaranteed encoding, matches UTF-8 is 8 bit + dos.writeBoolean(isPacketIdEvenParity); + + dos.flush(); // sends DataOutputStream to ByteArrayOutputStream + byteArray = baos.toByteArray(); // OK so go get the flushed result... + datagramPacket.setData(byteArray); // and put it in the packet... + udpSocket.send(datagramPacket); // and send it away. boom gone, nonblocking. +// System.out.println("udpSocket output port=" + udpSocket.getLocalPort()); // diagnostic tells what port was chosen by system + + if (isPacketIdEvenParity) + padding = " "; + else padding = ""; + + Thread.sleep(1000); // Send packets at rate of one per second + System.out.println("[" + UdpSender.class.getName() + "] " + MY_NAME + " " + sourceAddress + + " sent values(" + packetID + "," + value + ",\"" + message + "\"," + isPacketIdEvenParity + + ")" + padding + " as packet #" + index + " of " + TOTAL_PACKETS_TO_SEND); + baos.reset(); // clear the output stream after sending + } + } + catch (IOException | InterruptedException e) + { + System.err.println("Problem with UdpSender, see exception trace:"); + System.err.println(e); + } + finally // clean up prior to exit, don't want to leave behind zombies + { + if (udpSocket != null) + udpSocket.close(); + + if (dos != null) + dos.close(); + System.out.println(UdpSender.class.getName() + " complete."); // all done + } + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/BrittSimulation.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/BrittSimulation.java new file mode 100644 index 0000000000000000000000000000000000000000..d5a2909abd3d68c07c88c2745ffd765d5cb40152 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/BrittSimulation.java @@ -0,0 +1,477 @@ +/** + * Copyright (c) 2008-2020, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package MV3500Cohort2020JulySeptember.homework4.Britt; + +import MV3500Cohort2020JulySeptember.homework4.White.working.*; +import MV3500Cohort2020JulySeptember.homework4.White.*; +import edu.nps.moves.dis7.enumerations.*; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class BrittSimulation +{ + // class variables + PduFactory pduFactory = new PduFactory(); + DisThreadedNetworkInterface disNetworkInterface; + DisThreadedNetworkInterface.PduListener pduListener; + Pdu receivedPdu; + + private String networkAddress = "10.1.105.7"; + private int networkPort = 2317; + + /** + * Constructor design goal: additional built-in initialization conveniences can go here + * to keep student efforts focused on the runSimulation() method. + */ + public BrittSimulation() + { + // Under consideration. Constructor is not currently needed. + } + + /** + * Utility Constructor + * @param address network address to use + * @param port corresponding network port to use + */ + public BrittSimulation(String address, int port) + { + setNetworkAddress(address); + + setNetworkPort(port); + } + + /** + * @return the networkAddress + */ + public String getNetworkAddress() + { + return networkAddress; + } + + /** + * @param networkAddress the networkAddress to set + */ + public final void setNetworkAddress(String networkAddress) + { + this.networkAddress = networkAddress; + } + + /** + * @return the networkPort + */ + public int getNetworkPort() + { + return networkPort; + } + + /** + * @param networkPort the networkPort to set + */ + public final void setNetworkPort(int networkPort) + { + this.networkPort = networkPort; + } + + /** + * Initialize network interface, choosing best available network interface + */ + public void setUpNetworkInterface() + { + disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); + + System.out.println("Network confirmation: address=" + disNetworkInterface.getMcastGroup() + " port=" + disNetworkInterface.getDisPort()); + pduListener = new DisThreadedNetworkInterface.PduListener() + { + /** Callback handler for listener */ + @Override + public void incomingPdu(Pdu newPdu) + { + receivedPdu = newPdu; + } + }; + disNetworkInterface.addListener(pduListener); + } + + /** All done, release network resources */ + public void tearDownNetworkInterface() + { + disNetworkInterface.removeListener(pduListener); + disNetworkInterface.kill(); + disNetworkInterface = null; + } + + /** + * Send a single Protocol Data Unit (PDU) of any type + * @param pdu the pdu to send + */ + private void sendSinglePdu(Pdu pdu) + { + try + { + disNetworkInterface.send(pdu); + Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally + } + catch (InterruptedException ex) + { + System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); + System.exit(1); + } + } + + /** + * Send EntityState, Fire, Comment PDUs + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + * @param entityStatePdu the ESPDU to send, if any + * @param firePdu the FirePDU to send, if any + * @param commentType enumeration value describing the narrative comment + * @param comments String array of narrative comments + */ + public void sendAllPdus(EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable length string + String... comments) + { + if (entityStatePdu != null) + sendPDU(entityStatePdu); + + if (firePdu != null) + sendPDU(firePdu); // bang + + if ((comments != null) && (comments.length > 0)) + { + ArrayList<String> newCommentsList = new ArrayList<>(); + for (int i = 0; i < comments.length; i++) + { + if (!comments[i].isEmpty()) + newCommentsList.add(comments[i]); // OK found something to send + } + if (!newCommentsList.isEmpty()) + { + if (commentType == null) + commentType = VariableRecordType.OTHER; + CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); + sendPDU(commentPdu); + } + } + } + + /** + * Main method is first executed when a program instance is loaded. + * @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a> + * @param args command-line arguments are an array of optional String parameters that are passed from execution environment during invocation + */ + public static void main(String[] args) + { + BrittSimulation thisProgram = new BrittSimulation(); // creates instance + + // initial execution: can handle args array of initialization arguments here + if (args.length == 2) + { + if ((args[0] != null) && !args[0].isEmpty()) + thisProgram.setNetworkAddress(args[0]); + + if ((args[1] != null) && !args[1].isEmpty()) + thisProgram.setNetworkPort(Integer.parseInt(args[1])); + } + else if (args.length != 0) + { + System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); + System.exit(-1); + } + // OK here we go... + + //thisProgram.setUpNetworkInterface(); + + thisProgram.runSimulation (); // customization code goes in there + + //thisProgram.tearDownNetworkInterface(); + } + + /** + * Programmer-modifiable method for defining and running a new simulation of interest. + * Support include DIS EntityStatePdu, FirePdu and CommentPdu all available for + * modification and sending in a simulation loop. + */ + @SuppressWarnings("SleepWhileInLoop") + public void runSimulation () + { + try + { + final double LOOP_DURATION_SECONDS = 1.0; // seconds + final int MAX_LOOP_COUNT = 10; + int loopCount = 0; + VariableRecordType narrativeType = VariableRecordType.OTHER; // of potential use + boolean simulationComplete = false; // sentinel variable as termination condition + boolean fireBool = false; + boolean destBool = false; + boolean resupBool = false; + // TODO reset clock to zero each time for consistent outputs. + + // your model setup: who's who in this zoo? + // create PDU objects and set their values + + Vector3Double eloc3 = new Vector3Double(); + double[] loc3 = CoordinateConversions.getXYZfromLatLonDegrees(36.600757, -121.869309, 0 );//NPS Corner by lake + + EntityID entityID_1 = new EntityID(); + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID + + EntityStatePdu entityStatePdu = pduFactory.makeEntityStatePdu(); + entityStatePdu.setEntityID(entityID_1); + + + + EntityID MTVRID = new EntityID(); + MTVRID.setSiteID(1); + MTVRID.setApplicationID(13); + MTVRID.setEntityID(26); + entityStatePdu.setEntityID(MTVRID); + EntityType MTVRType = new EntityType(); //1.1.225.7.39.3 MTVR + MTVRType.setEntityKind(EntityKind.PLATFORM); + MTVRType.setDomain(Domain.inst(PlatformDomain.LAND)); + MTVRType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + MTVRType.setCategory(7); + MTVRType.setSubCategory(39); + MTVRType.setSpecific(3); + entityStatePdu.setEntityType(MTVRType); + Vector3Double eloc2 = new Vector3Double(); + double[] loc2 = CoordinateConversions.getXYZfromLatLonDegrees(36.599831, -121.878842, 0); //sloat delmonte intersection + eloc2.setX(loc2[0]); + eloc2.setY(loc2[1]); + eloc2.setZ(loc2[2]); + entityStatePdu.setEntityLocation(eloc2); + EulerAngles orient2 = new EulerAngles(); + orient2.setPhi((float) 0.0); + orient2.setPsi((float) 0.0); + orient2.setTheta((float) 0.0); + entityStatePdu.setEntityOrientation(orient2); + + EntityStatePdu entityStatePdu2 = pduFactory.makeEntityStatePdu(); + + + + EntityID lavID = new EntityID(); + lavID.setSiteID(1); + lavID.setApplicationID(13); + lavID.setEntityID(25); + entityStatePdu2.setEntityID(lavID); + EntityType lavType = new EntityType(); //1.1.225.2.41.3 Platform,Ground,USA,ArmoredFightingVehicle,LAV,LAV25A2 + lavType.setEntityKind(EntityKind.PLATFORM); + lavType.setDomain(Domain.inst(PlatformDomain.LAND)); + lavType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + lavType.setCategory(2); + lavType.setSubCategory(41); + lavType.setSpecific(3); + entityStatePdu2.setEntityType(lavType); + Vector3Double eloc1 = new Vector3Double(); + double[] loc1 = CoordinateConversions.getXYZfromLatLonDegrees(36.594116, -121.877463, 0); //NPS Main Gate + eloc1.setX(loc1[0]); + eloc1.setY(loc1[1]); + eloc1.setZ(loc1[2]); + + entityStatePdu2.setEntityLocation(eloc1); + EulerAngles orient1 = new EulerAngles(); + orient1.setPhi((float) 0.0); + orient1.setPsi((float) 0.0); + orient1.setTheta((float) 0.0); + entityStatePdu2.setEntityOrientation(orient1); + + int BMPHitsReceived = 0; + + System.out.println(eloc2.toString()); + System.out.println(eloc1.toString()); + + //FirePdu firePduNull = new FirePdu(); + FirePdu firePdu = pduFactory.makeFirePdu(); + EntityID fireID = new EntityID(); + fireID.setSiteID(1); + fireID.setApplicationID(13); + fireID.setEntityID(26); + EntityID targetID = new EntityID(); + targetID.setSiteID(1); + targetID.setApplicationID(13); + targetID.setEntityID(27); + + firePdu.setFiringEntityID(fireID); + firePdu.setTargetEntityID(targetID); + + EntityType HEType = new EntityType(); //2.9.225.2.2.1 + HEType.setEntityKind(EntityKind.MUNITION); + HEType.setDomain(Domain.inst(PlatformDomain.AIR)); + HEType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + HEType.setCategory(2); + HEType.setSubCategory(2); + HEType.setSpecific(1); + MunitionDescriptor HEIT = new MunitionDescriptor(); + HEIT.setMunitionType(HEType); + HEIT.setQuantity(3); + HEIT.setFuse(MunitionDescriptorFuse.CONTACT_GRAZE); + HEIT.setRate(200); + + firePdu.setDescriptor(HEIT); + EntityID HEID = new EntityID(); + HEID.setEntityID(1); + firePdu.setMunitionExpendibleID(HEID); + + ResupplyOfferPdu resupplyOfferPdu = pduFactory.makeResupplyOfferPdu(); + + ArrayList<SupplyQuantity> pSupplies = new ArrayList<SupplyQuantity>(); + SupplyQuantity ammoSupplyQ = new SupplyQuantity(); + ammoSupplyQ.setSupplyType(HEType); + ammoSupplyQ.setQuantity(500); + pSupplies.add(ammoSupplyQ); + resupplyOfferPdu.setSupplies(pSupplies); + resupplyOfferPdu.setReceivingEntityID(lavID); + resupplyOfferPdu.setSupplyingEntityID(MTVRID); + + CommentReliablePdu bmpDestroyedComment = pduFactory.makeCommentReliablePdu("BMP2 DESTROYED BY LAV25-A2 AFTER TWO BURSTS OF 25mm HEI-T ON TARGET"); + CommentReliablePdu bmpSightedComment = pduFactory.makeCommentReliablePdu("LAV25-A2 ACQUIRES TARGET BMP2 WITHIN FIRING DISTANCE"); + CommentReliablePdu lavSightedComment = pduFactory.makeCommentReliablePdu("LAV25-A2 IS WITHIN DISTANCE OF RESUPPLY"); +//if(eloc1.getX()) + + // should we customize this munition? what is it for your simulation? + + while (loopCount < MAX_LOOP_COUNT) // loop the simulation while allowed, can set additional conditions to break + { + String narrativeMessage1, narrativeMessage2, narrativeMessage3, narrativeMessage4; + narrativeMessage4 = ""; + // initialize loop variables + loopCount++; + + // ============================================================================================= + // your own simulation code starts here! + + // compute a track, update an ESPDU, whatever it is that your model is doing... + + // Where is my entity? + entityStatePdu.getEntityLocation().setX(entityStatePdu.getEntityLocation().getX() - 20); // 1m per timestep + entityStatePdu.getEntityLocation().setY(entityStatePdu.getEntityLocation().getY() - 75); + // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoort at! + Double dx = eloc2.getX() - eloc1.getX(); + Double dy = eloc2.getY() - eloc1.getY(); + Double dz = eloc2.getZ() - eloc1.getZ(); + Double range = Math.sqrt(dx*dx + dy*dy); + System.out.println("range" + range + " dx:" +dx + " dy:"+ dy); + // etc. etc. your code goes here + + if(range < 100){ + if (!resupBool) + sendPDU(lavSightedComment); + resupBool = true; + System.out.println("Entity#" + entityStatePdu.getEntityID().getEntityID() + " is requesting to resupply " + " Entity#"+ entityStatePdu2.getEntityID().getEntityID()); + + + + + + if(firePdu.getTargetEntityID().getEntityID() == 2){ + BMPHitsReceived += 1; + if (BMPHitsReceived > 1) { + //DESTROY THE BMP! + + System.out.println("BMP Destroyed after "+ BMPHitsReceived + " hits from 25mm HEI-T"); + narrativeMessage4 = "Destroyed BMP2"; + destBool = true; + + } + } + } + + // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) + narrativeMessage1 = "MV3500 ExampleSimulationProgram"; + narrativeMessage2 = "runSimulation() loop " + loopCount; + narrativeMessage3 = "LAV-25A2"; // intentionally blank for testing + if (narrativeMessage4.isEmpty()){ + narrativeMessage4 = "BMP2"; + } + // your loop termination condition goes here + if (loopCount > 4) // for example + { + simulationComplete = true; + } + // your own simulation code is finished here! + // ============================================================================================= + + // keep track of timestep: wait duration for elapsed time in this loop + // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes + Thread.sleep((long)(LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds + System.out.println ("... Pausing for " + LOOP_DURATION_SECONDS + " seconds"); + + // send the status PDUs for this loop and continue + System.out.println ("sending PDUs for simulation step " + loopCount + ", monitor loopback to confirm sent"); + //sendAllPdus(entityStatePdu, firePduNull, null, narrativeMessage1, narrativeMessage2, narrativeMessage3); + //sendAllPdus(entityStatePdu2, null, null, narrativeMessage1, narrativeMessage2, narrativeMessage4); + sendPDU(entityStatePdu); + sendPDU(entityStatePdu2); + if (resupBool) + sendPDU(resupplyOfferPdu); + if (destBool) + sendPDU(bmpDestroyedComment); + + System.out.println ("... PDUs successfully sent"); + + // =============================== + // loop now finished, thus terminate if simulation complete, otherwise send latest PDUs and continue + if (simulationComplete || (loopCount > 10000)) // for example; including fail-safe condition is good + { + CommentReliablePdu completionPdu = pduFactory.makeCommentReliablePdu("Britt Simulation Completed"); + sendPDU(completionPdu); + System.out.println ("... Termination condition met, simulationComplete=" + simulationComplete); + break; + } + } // end of while loop + } + catch (Exception ex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(BrittSimulation.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public void sendPDU(Pdu pdu) { + System.out.println("Sending a PDU"); + MulticastSocket socket = null; // must be initialized, even if null + InetAddress destinationIp = null; // must be initialized, even if null + + try { + destinationIp = InetAddress.getByName(networkAddress); + } catch (UnknownHostException e) { + System.out.println(e + " Cannot create address"); + System.exit(0); + } + try { + // Set up a socket to send information + socket = new MulticastSocket(2317); + } catch (IOException ex) { + Logger.getLogger(BrittSimulation.class.getName()).log(Level.SEVERE, null, ex); + } + + Set<InetAddress> broadcastAddresses; + // Loop through sending one ESPDUs + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + try { + pdu.marshal(dos); + byte[] data = baos.toByteArray(); + + DatagramPacket packet = new DatagramPacket(data, data.length, destinationIp, 2317); + socket.send(packet); + socket.close(); + } catch (Exception ex) { + Logger.getLogger(BrittSimulation.class.getName()).log(Level.SEVERE, null, ex); + } +} +} \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/EspduSender.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/EspduSender.java new file mode 100644 index 0000000000000000000000000000000000000000..7a4225844410726cd3fe39440e50c02bc31ccf98 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/EspduSender.java @@ -0,0 +1,413 @@ +package OpenDis7Examples; + +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.enumerations.Country; +import edu.nps.moves.dis7.enumerations.EntityKind; +import edu.nps.moves.dis7.enumerations.PlatformDomain; +import edu.nps.moves.dis7.utilities.*; +import edu.nps.moves.dis7.entities.usa.platform.land.M1A2; +import edu.nps.moves.dis7.entities.usa.platform.land.MTVRMK25Cargo; + +/** + * Creates and sends ESPDUs in IEEE binary format. Adapted from OpenDIS library + * example package edu.nps.moves.examples + * + * @author Don McGregor + * @author Don Brutzman + */ +public class EspduSender +{ + /** + * Putting any upper limit on # packets sent avoids possibility of non-terminating infinite loops that continue sending packets. + */ + public static final int NUMBER_OF_LOOPS = 2; // 5 + + /** + * Default multicast group address we send on. + */ + public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; + + /** + * Default multicast port used, matches Wireshark DIS capture default + */ + public static final int DEFAULT_MULTICAST_PORT = 3000; + + public enum NetworkMode { + UNICAST, MULTICAST, BROADCAST + }; + + /** + * Output prefix to identify this class, helps with logging + */ + private final static String TRACE_PREFIX = "[" + EspduSender.class.getName() + "] "; + + /** + * Possible system properties, passed in via -Dattr=val networkMode: + * unicast, broadcast, multicast destinationIp: where to send the packet. If + * in multicast mode, this can be multicast. To determine broadcast + * destination IP, use an online broadcast address calculator, for example + * http://www.remotemonitoringsystems.ca/broadcast.php If in multicast mode, + * a join() will be done on the multicast address. port: port used for both + * source and destination. + * + * @param args + */ + @SuppressWarnings("SleepWhileInLoop") // allows Thread.sleep(value) without warning in code + public static void main(String args[]) + { + System.out.println(TRACE_PREFIX + " started..."); + + // Default settings. These are used if no system properties are set. + // If system properties are passed in, these are overridden later. + NetworkMode networkMode = NetworkMode.MULTICAST; + InetAddress address = null; // must be initialized, even if null + int port = DEFAULT_MULTICAST_PORT; + MulticastSocket socket = null; // must be initialized to avoid later error, even if null; + EntityStatePdu espdu = new EntityStatePdu(); + DisTime disTime = new DisTime(); + + // ICBM coordinates for my office + double latitude = 36.639222; + double longitude = -121.803415; + try + { + address = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); + } + catch (UnknownHostException e) + { + System.out.println(TRACE_PREFIX + e + " Cannot create multicast address"); + System.exit(0); + } + + // All system properties, passed in on the command line via -Dattribute=value + Properties systemProperties = System.getProperties(); + + // IP address we send to + String destinationIpString = systemProperties.getProperty("destinationIp"); + + // Port we send to, and local port we open the socket on + String portString = systemProperties.getProperty("port"); + + // Network mode: unicast, multicast, broadcast + String networkModeString = systemProperties.getProperty("networkMode"); // unicast or multicast or broadcast + + // Set up socket to send information + try + { + if (portString != null) // Update port we send to, if provided + { + port = Integer.parseInt(portString); + } + socket = new MulticastSocket(port); + + // Where we send packets to, the destination IP address + if (destinationIpString != null) + { + address = InetAddress.getByName(destinationIpString); + } + + // Type of transport: unicast, broadcast, or multicast + if (networkModeString != null) + { + if (networkModeString.equalsIgnoreCase("unicast")) + { + networkMode = NetworkMode.UNICAST; + } + else if (networkModeString.equalsIgnoreCase("broadcast")) + { + networkMode = NetworkMode.BROADCAST; + } + else if (networkModeString.equalsIgnoreCase("multicast")) + { + networkMode = NetworkMode.MULTICAST; + if (!address.isMulticastAddress()) + { + throw new RuntimeException("*** Error: sending to multicast address, but destination address " + address.toString() + "is not multicast"); + } + socket.joinGroup(address); // TODO select correct NetworkInterface + } + } // end networkModeString + else if (networkMode == NetworkMode.MULTICAST) + { + networkModeString = "multicast"; + } + else if (networkMode == NetworkMode.UNICAST) + { + networkModeString = "unicast"; + } + else if (networkMode == NetworkMode.BROADCAST) + { + networkModeString = "broadcast"; + } + } + catch (IOException | RuntimeException e) + { + System.out.println(TRACE_PREFIX + "Unable to initialize network correctly, exiting."); + System.out.println(e); + System.exit(-1); // outta here + } + System.out.println(TRACE_PREFIX + " sending " + networkModeString + " ESPDU packets to " + + address.getHostAddress() + " port " + port); + + // Initialize values in the Entity State PDU object. The exercise ID is + // a way to differentiate between different virtual worlds on one network. + // Note that some values (such as the PDU type and PDU family) are set + // automatically when you create the ESPDU. + espdu.setExerciseID((byte)1); //(short) 1); + + // The EID is the unique identifier for objects in the world. This + // EID should match up with the ID for the object specified in the + // VMRL/x3d/virtual world. + + EntityID entityID = espdu.getEntityID(); // initialize, reset, override + // TODO check: 0 is apparently not a valid site number, per DIS specification + entityID.setSiteID ((short)1); // TODO utility method to allow int values + entityID.setApplicationID((short)2); + entityID.setEntityID ((short)3); + espdu.setEntityID(entityID); // TODO utility method to allow setting all three at once + + // Set the entity type. SISO has a big list of enumerations, so that by + // specifying various numbers we can say this is an M1A2 American tank, + // the USS Enterprise, and so on. We'll make this a tank. There is a + // separate project elsehwhere in this project that implements DIS + // enumerations in C++ and Java, but to keep things simple we just use + // numbers here. + + // Manual way to override platform information: + EntityType entityType = espdu.getEntityType() + .setEntityKind (EntityKind.PLATFORM).setEntityKind (EntityKind.PLATFORM) //(short) 1); // Platform (vs lifeform, munition, sensor, etc.); //(short) 1); // Platform (vs lifeform, munition, sensor, etc.) + .setCountry (Country.UNITED_STATES_OF_AMERICA_USA) // 225 USA + .setDomain (Domain.inst(PlatformDomain.LAND)) // Land (vs air, surface, subsurface, space) + .setCategory ((byte) 7) // Large vic + .setSubCategory((byte) 39) // MTVR + .setSpecific ((byte) 2); // MTVR + + // New way using entity jar(s) + espdu.setEntityType(new edu.nps.moves.dis7.entities.usa.platform.land.MTVRMK25Cargo()); + // or simply use an enumeration by name, with accompanying import statement above + espdu.setEntityType(new MTVRMK25Cargo()); + + // Inspecting an enumeration + System.out.println("==============="); + System.out.println("espdu entityType information:"); + System.out.println(" EntityKind =" + espdu.getEntityType().getEntityKind()); + System.out.println(" Country =" + espdu.getEntityType().getCountry()); + System.out.println(" Domain =" + espdu.getEntityType().getDomain()); + System.out.println(" Category =" + espdu.getEntityType().getCategory()); + System.out.println(" SubCategory=" + espdu.getEntityType().getSubCategory()); + System.out.println(" Specific =" + espdu.getEntityType().getCountry()); + System.out.println("I am an MTVRMK25 Cargo Truck"); + // TODO round trip lookup + + Set<InetAddress> localNetworkAddresses; + + try // Loop through sending N ESPDUs + { + System.out.println(TRACE_PREFIX + "sending " + NUMBER_OF_LOOPS + " sets of packets:"); // + address.toString() + + for (int index = 0; index < NUMBER_OF_LOOPS; index++) + { + // DIS time is a pain in the uh, neck. DIS time units are 2^31-1 units per + // hour, and time is set to DIS time units from the top of the hour. + // This means that if you start sending just before the top of the hour + // the time units can roll over to zero as you are sending. The receivers + // (escpecially homegrown ones) are often not able to detect rollover + // and may start discarding packets as dupes or out of order. We use + // an NPS timestamp here, hundredths of a second since the start of the + // year. The DIS standard for time is often ignored in the wild; I've seen + // people use Unix time (seconds since 1970) and more. Or you can + // just stuff idx into the timestamp field to get something that is monotonically + // increasing. + + // Note that timestamp is used to detect duplicate and out of order packets. + // That means if you DON'T change the timestamp, many implementations will simply + // discard subsequent packets that have an identical timestamp. Also, if they + // receive a PDU with an timestamp lower than the last one they received, they + // may discard it as an earlier, out-of-order PDU. So it is a good idea to + // update the timestamp on ALL packets sent. + // An alterative approach: actually follow the standard. It's a crazy concept, + // but it might just work. + int timestamp = disTime.getDisAbsoluteTimestamp(); + espdu.setTimestamp(timestamp); + + // Set the position of the entity in the world. DIS uses a cartesian + // coordinate system with the origin at the center of the earth, the x + // axis out at the equator and prime meridian, y out at the equator and + // 90 deg east, and z up and out the north pole. To place an object on + // the earth's surface you also need a model for the shape of the earth + // (it's not a sphere.) All the fancy math necessary to do this is in + // the SEDRIS SRM package. There are also some one-off formulas for + // doing conversions from, for example, lat/lon/altitude to DIS coordinates. + // Here we use those one-off formulas. + // Modify the position of the object. This will send the object a little + // due east by adding some to the longitude every iteration. Since we + // are on the Pacific coast, this sends the object east. Assume we are + // at zero altitude. In other worlds you'd use DTED to determine the + // local ground altitude at that lat/lon, or you'd just use ground clamping. + // The x and y values will change, but the z value should not. + //lon = lon + (double)((double)idx / 100000.0); + //System.out.println("lla=" + lat + "," + lon + ", 0.0"); + double direction = Math.pow(-1.0, index); + longitude = longitude + (direction * 0.00006); + + double disCoordinates[] = CoordinateConversions.getXYZfromLatLonDegrees(latitude, longitude, 1.0); + Vector3Double location = espdu.getEntityLocation(); + location.setX(disCoordinates[0]); + location.setY(disCoordinates[1]); + location.setZ(disCoordinates[2]); + System.out.println("==============="); + System.out.println("Create new PDUs"); + System.out.println(" latitude, longitude: [" + latitude + ", " + longitude + "]"); + System.out.println(" coordinate conversion: [" + disCoordinates[0] + ", " + disCoordinates[1] + ", " + disCoordinates[2] + "]"); + + location = espdu.getEntityLocation(); + + System.out.println("Espdu #" + index + " entityID=[" + entityID.getSiteID()+ "," + entityID.getApplicationID()+ "," + entityID.getEntityID()+ "]"); + double c[] = {location.getX(), location.getY(), location.getZ()}; + double lla[] = CoordinateConversions.xyzToLatLonDegrees(c); +// System.out.println(" DIS entityLocation: [" + location.getX() + "," + location.getY() + "," + location.getZ() + "]"); + String debugString = " Location (latitude/longitude/altitude): [" + lla[0] + ", " + lla[1] + ", " + lla[2] + "]"; +// System.out.println(debugString); + + // Optionally, we can do some rotation of the entity + /* + Orientation orientation = espdu.getEntityOrientation(); + float psi = orientation.getPsi(); + psi = psi + idx; + orientation.setPsi(psi); + orientation.setTheta((float)(orientation.getTheta() + idx /2.0)); + */ + // You can set other ESPDU values here, such as the velocity, acceleration, + // and so on. + // Marshal out the espdu object to a byte array, then send a datagram + // packet with that data in it. + + double[] locOr = {location.getX(),location.getY(),location.getZ(), 5,6,1, 1,2,1, 0,0,0, 0,0,0}; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + DatagramPacket packet; + + // The byte array here is the packet in DIS format. We put that into a + // datagram and send it. + espdu.marshal(dos); + byte[] espduArray = baos.toByteArray(); + + FirePdu firePdu = new FirePdu(); + firePdu.setLocationInWorldCoordinates(espdu.getEntityLocation()); + byte[] fireArray = firePdu.marshal(); + +// CommentPdu newCommentPdu = new CommentPdu(); +// ArrayList<VariableDatum> payloadList = new ArrayList<>(); +// ArrayList<String> commentsList = new ArrayList<>(); +// commentsList.add("Hello CommentPDU"); +// commentsList.add("Here is a second line of text in this comment."); +// if (!commentsList.isEmpty()) +// System.out.println("Preparing CommentPDU:"); +// +// for (String comment : commentsList) +// { +// VariableDatum newVariableDatum = new VariableDatum(); +// newVariableDatum.setVariableDatumValue (comment.getBytes()); // conversion +// newVariableDatum.setVariableDatumLengthInBytes(comment.getBytes().length); // also available in bits, see spec and javadoc +// // alternatively, you do not need to set this and the marshaller will figure it out from the byte array +// // (see javadoc for VariableDatum.setVariableDatumLength()) +// payloadList.add(newVariableDatum); +// System.out.println(" \"" + comment + "\""); +// } +// newCommentPdu.setVariableDatums(payloadList); +// byte[] commentArray = newCommentPdu.marshal(); + + localNetworkAddresses = getBroadcastAddresses(); + for (InetAddress networkAddress : localNetworkAddresses) { + if (espduArray.length > 0) + { + System.out.println(TRACE_PREFIX + "sending datagram packet [" + espdu.getPduType().toString() + "] to " + + String.format("%-15s", networkAddress.getHostAddress()) + " port " + port); + packet = new DatagramPacket(espduArray, espduArray.length, networkAddress, port); + socket.send(packet); + } + // TODO experiment with these! 8) + if (fireArray.length > 0) + { + System.out.println(TRACE_PREFIX + "sending datagram packet [" + firePdu.getPduType().toString() + " ] to " + + String.format("%-15s", networkAddress.getHostAddress()) + " port " + port); + packet = new DatagramPacket(fireArray, fireArray.length, networkAddress, port); // alternate + socket.send(packet); + } +// // TODO experiment with these! 8) +// if (newCommentPdu != null) +// { +// System.out.println(TRACE_PREFIX + "sending datagram packet [" + newCommentPdu.getPduType().toString() + " ] to " + +// String.format("%-15s", networkAddress.getHostAddress()) + " port " + port); +// packet = new DatagramPacket(commentArray, commentArray.length, networkAddress, port); // alternate +// socket.send(packet); +// } + } + // Send every 1 second within loop. Otherwise all this will be all over in a fraction of a second. + Thread.sleep(1000); // msec + } + } + catch (Exception e) + { + System.out.println(TRACE_PREFIX + "Problem with " + e + ", see exception trace:"); + System.out.println(e); + } + System.out.println("==============="); + System.out.println(TRACE_PREFIX + "complete."); + } + + /** + * A number of sites get all snippy about using 255.255.255.255 for a + * broadcast address; it trips their security software and they kick you off + * their network. (Comcast, NPS, etc.) This determines the broadcast address for + * all connected interfaces, based on the IP and subnet mask. If you have a + * dual-homed host it will return a broadcast address for both. If you have + * some VMs running on your host this will pick up the addresses for those + * as well--e.g. running VMWare on your laptop with a local IP this will also + * pick up a 192.168 address assigned to the VM by the host OS. + * + * @return set of all broadcast addresses + */ + public static Set<InetAddress> getBroadcastAddresses() + { + Set<InetAddress> broadcastAddresses = new HashSet<>(); + Enumeration interfaces; + + try { + interfaces = NetworkInterface.getNetworkInterfaces(); + + while (interfaces.hasMoreElements()) + { + NetworkInterface anInterface = (NetworkInterface) interfaces.nextElement(); + + if (anInterface.isUp()) + { + for (InterfaceAddress anAddress : anInterface.getInterfaceAddresses()) { + if ((anAddress == null || anAddress.getAddress().isLinkLocalAddress())) + { + continue; + } + + //System.out.println("Getting broadcast address for " + anAddress); + InetAddress broadcastAddress = anAddress.getBroadcast(); + if (broadcastAddress != null) + { + broadcastAddresses.add(broadcastAddress); + } + } + } + } + } + catch (SocketException e) + { + System.out.println(TRACE_PREFIX + "Problem with .getBroadcastAddresses(), see exception trace:" + e); + System.out.println(e); + } + return broadcastAddresses; + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/ExampleSimulationProgram.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/ExampleSimulationProgram.java new file mode 100644 index 0000000000000000000000000000000000000000..0b3f007706a8281e7f1e02ed0d72b463329a86bf --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/ExampleSimulationProgram.java @@ -0,0 +1,399 @@ +/** + * Copyright (c) 2008-2020, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package MV3500Cohort2020JulySeptember.homework4.Britt; + +import edu.nps.moves.dis7.enumerations.*; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ExampleSimulationProgram +{ + // class variables + PduFactory pduFactory = new PduFactory(); + DisThreadedNetworkInterface disNetworkInterface; + DisThreadedNetworkInterface.PduListener pduListener; + Pdu receivedPdu; + + private String networkAddress = "239.1.2.3"; + private int networkPort = 3000; + + /** + * Constructor design goal: additional built-in initialization conveniences can go here + * to keep student efforts focused on the runSimulation() method. + */ + public ExampleSimulationProgram() + { + // Under consideration. Constructor is not currently needed. + } + + /** + * Utility Constructor + * @param address network address to use + * @param port corresponding network port to use + */ + public ExampleSimulationProgram(String address, int port) + { + setNetworkAddress(address); + + setNetworkPort(port); + } + + /** + * @return the networkAddress + */ + public String getNetworkAddress() + { + return networkAddress; + } + + /** + * @param networkAddress the networkAddress to set + */ + public final void setNetworkAddress(String networkAddress) + { + this.networkAddress = networkAddress; + } + + /** + * @return the networkPort + */ + public int getNetworkPort() + { + return networkPort; + } + + /** + * @param networkPort the networkPort to set + */ + public final void setNetworkPort(int networkPort) + { + this.networkPort = networkPort; + } + + /** + * Initialize network interface, choosing best available network interface + */ + public void setUpNetworkInterface() + { + disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); + + System.out.println("Network confirmation: address=" + disNetworkInterface.getMcastGroup() + " port=" + disNetworkInterface.getDisPort()); + pduListener = new DisThreadedNetworkInterface.PduListener() + { + /** Callback handler for listener */ + @Override + public void incomingPdu(Pdu newPdu) + { + receivedPdu = newPdu; + } + }; + disNetworkInterface.addListener(pduListener); + } + + /** All done, release network resources */ + public void tearDownNetworkInterface() + { + disNetworkInterface.removeListener(pduListener); + disNetworkInterface.kill(); + disNetworkInterface = null; + } + + /** + * Send a single Protocol Data Unit (PDU) of any type + * @param pdu the pdu to send + */ + private void sendSinglePdu(Pdu pdu) + { + try + { + disNetworkInterface.send(pdu); + Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally + } + catch (InterruptedException ex) + { + System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); + System.exit(1); + } + } + + /** + * Send EntityState, Fire, Comment PDUs + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + * @param entityStatePdu the ESPDU to send, if any + * @param firePdu the FirePDU to send, if any + * @param commentType enumeration value describing the narrative comment + * @param comments String array of narrative comments + */ + public void sendAllPdus(EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable length string + String... comments) + { + if (entityStatePdu != null) + sendSinglePdu(entityStatePdu); + + if (firePdu != null) + sendSinglePdu(firePdu); // bang + + if ((comments != null) && (comments.length > 0)) + { + ArrayList<String> newCommentsList = new ArrayList<>(); + for (int i = 0; i < comments.length; i++) + { + if (!comments[i].isEmpty()) + newCommentsList.add(comments[i]); // OK found something to send + } + if (!newCommentsList.isEmpty()) + { + if (commentType == null) + commentType = VariableRecordType.OTHER; + CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); + sendSinglePdu(commentPdu); + } + } + } + + /** + * Main method is first executed when a program instance is loaded. + * @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a> + * @param args command-line arguments are an array of optional String parameters that are passed from execution environment during invocation + */ + public static void main(String[] args) + { + ExampleSimulationProgram thisProgram = new ExampleSimulationProgram(); // creates instance + + // initial execution: can handle args array of initialization arguments here + if (args.length == 2) + { + if ((args[0] != null) && !args[0].isEmpty()) + thisProgram.setNetworkAddress(args[0]); + + if ((args[1] != null) && !args[1].isEmpty()) + thisProgram.setNetworkPort(Integer.parseInt(args[1])); + } + else if (args.length != 0) + { + System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); + System.exit(-1); + } + // OK here we go... + + thisProgram.setUpNetworkInterface(); + + thisProgram.runSimulation (); // customization code goes in there + + thisProgram.tearDownNetworkInterface(); + } + + /** + * Programmer-modifiable method for defining and running a new simulation of interest. + * Support include DIS EntityStatePdu, FirePdu and CommentPdu all available for + * modification and sending in a simulation loop. + */ + @SuppressWarnings("SleepWhileInLoop") + public void runSimulation () + { + try + { + final double LOOP_DURATION_SECONDS = 1.0; // seconds + final int MAX_LOOP_COUNT = 10; + int loopCount = 0; + VariableRecordType narrativeType = VariableRecordType.OTHER; // of potential use + boolean simulationComplete = false; // sentinel variable as termination condition + + // TODO reset clock to zero each time for consistent outputs. + + // your model setup: who's who in this zoo? + // create PDU objects and set their values + + Vector3Double eloc3 = new Vector3Double(); + double[] loc3 = CoordinateConversions.getXYZfromLatLonDegrees(36.600757, -121.869309, 0 );//NPS Corner by lake + + EntityID entityID_1 = new EntityID(); + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID + + EntityStatePdu entityStatePdu = pduFactory.makeEntityStatePdu(); + entityStatePdu.setEntityID(entityID_1); + + + + EntityID M49ID = new EntityID(); + M49ID.setSiteID(1); + M49ID.setApplicationID(13); + M49ID.setEntityID(26); + entityStatePdu.setEntityID(M49ID); + EntityType M49Type = new EntityType(); //1.1.225.7.1.11 Platform,Ground,USA,M49 + M49Type.setEntityKind(EntityKind.PLATFORM); + M49Type.setDomain(Domain.inst(PlatformDomain.LAND)); + M49Type.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + M49Type.setCategory(7); + M49Type.setSubCategory(1); + M49Type.setSpecific(11); + entityStatePdu.setEntityType(M49Type); + Vector3Double eloc2 = new Vector3Double(); + double[] loc2 = CoordinateConversions.getXYZfromLatLonDegrees(36.599831, -121.878842, 0); //sloat delmonte intersection + eloc2.setX(loc2[0]); + eloc2.setY(loc2[1]); + eloc2.setZ(loc2[2]); + entityStatePdu.setEntityLocation(eloc2); + EulerAngles orient2 = new EulerAngles(); + orient2.setPhi((float) 0.0); + orient2.setPsi((float) 0.0); + orient2.setTheta((float) 0.0); + entityStatePdu.setEntityOrientation(orient2); + + EntityStatePdu entityStatePdu2 = pduFactory.makeEntityStatePdu(); + + + EntityID NPSID = new EntityID(); + NPSID.setSiteID(1); + NPSID.setApplicationID(13); + NPSID.setEntityID(27); + entityStatePdu2.setEntityID(NPSID); + EntityType NPSType = new EntityType(); //5.1.0.14.1.3 NPS Building not sure if this is the right info but its the enumeration of a building in the siso doc + NPSType.setEntityKind(EntityKind.CULTURAL_FEATURE); + NPSType.setDomain(Domain.inst(PlatformDomain.LAND)); + NPSType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + NPSType.setCategory(14); + NPSType.setSubCategory(1); + NPSType.setSpecific(3); + entityStatePdu2.setEntityType(NPSType); + Vector3Double eloc1 = new Vector3Double(); + double[] loc1 = CoordinateConversions.getXYZfromLatLonDegrees(36.594116, -121.877463, 0); //NPS Main Gate + eloc1.setX(loc1[0]); + eloc1.setY(loc1[1]); + eloc1.setZ(loc1[2]); + + entityStatePdu2.setEntityLocation(eloc1); + EulerAngles orient1 = new EulerAngles(); + orient1.setPhi((float) 0.0); + orient1.setPsi((float) 0.0); + orient1.setTheta((float) 0.0); + entityStatePdu2.setEntityOrientation(orient1); + + int BMPHitsReceived = 0; + + System.out.println(eloc2.toString()); + System.out.println(eloc1.toString()); + + FirePdu firePduNull = new FirePdu(); + FirePdu firePdu = pduFactory.makeFirePdu(); + EntityID fireID = new EntityID(); + fireID.setSiteID(1); + fireID.setApplicationID(13); + fireID.setEntityID(26); + EntityID targetID = new EntityID(); + targetID.setSiteID(1); + targetID.setApplicationID(13); + targetID.setEntityID(27); + + firePdu.setFiringEntityID(fireID); + firePdu.setTargetEntityID(targetID); + + EntityType HEType = new EntityType(); //2.9.225.2.2.1 + HEType.setEntityKind(EntityKind.MUNITION); + HEType.setDomain(Domain.inst(PlatformDomain.AIR)); + HEType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + HEType.setCategory(2); + HEType.setSubCategory(2); + HEType.setSpecific(1); + MunitionDescriptor HEIT = new MunitionDescriptor(); + HEIT.setMunitionType(HEType); + HEIT.setQuantity(3); + HEIT.setFuse(MunitionDescriptorFuse.CONTACT_GRAZE); + HEIT.setRate(200); + firePdu.setDescriptor(HEIT); + EntityID HEID = new EntityID(); + HEID.setEntityID(1); + firePdu.setMunitionExpendibleID(HEID); + + //if(eloc1.getX()) + + // should we customize this munition? what is it for your simulation? + + while (loopCount < MAX_LOOP_COUNT) // loop the simulation while allowed, can set additional conditions to break + { + String narrativeMessage1, narrativeMessage2, narrativeMessage3, narrativeMessage4; + narrativeMessage4 = ""; + // initialize loop variables + loopCount++; + + // ============================================================================================= + // your own simulation code starts here! + + // compute a track, update an ESPDU, whatever it is that your model is doing... + + // Where is my entity? + entityStatePdu.getEntityLocation().setX(entityStatePdu.getEntityLocation().getX() - 10); // 1m per timestep + entityStatePdu.getEntityLocation().setY(entityStatePdu.getEntityLocation().getY() - 75); + // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoort at! + Double dx = eloc2.getX() - eloc1.getX(); + Double dy = eloc2.getY() - eloc1.getY(); + Double dz = eloc2.getZ() - eloc1.getZ(); + Double range = Math.sqrt(dx*dx + dy*dy); + System.out.println(range + " " +dx + " "+ dy); + // etc. etc. your code goes here + + if(range < 100){ + firePduNull = firePdu; + System.out.println("Entity#" + firePdu.getFiringEntityID().getEntityID() + " is firing " + firePdu.getDescriptor().getMunitionType().getDomain() + "."+firePdu.getDescriptor().getMunitionType().getCountry() + "." + firePdu.getDescriptor().getMunitionType().getCategory() + "."+ firePdu.getDescriptor().getMunitionType().getSubCategory() + "." + firePdu.getDescriptor().getMunitionType().getSpecific() + "."+ " at Entity#"+ firePdu.getTargetEntityID().getEntityID()); + } + + if(firePduNull.getTargetEntityID().getEntityID() == 2){ + BMPHitsReceived += 1; + if (BMPHitsReceived > 1) { + //DESTROY THE BMP! + + System.out.println("BMP Destroyed after "+ BMPHitsReceived + " hits from 25mm HEI-T"); + narrativeMessage4 = "Destroyed BMP2"; + } + } + + + // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) + narrativeMessage1 = "MV3500 ExampleSimulationProgram"; + narrativeMessage2 = "runSimulation() loop " + loopCount; + narrativeMessage3 = "LAV-25A2"; // intentionally blank for testing + if (narrativeMessage4.isEmpty()){ + narrativeMessage4 = "BMP2"; + } + // your loop termination condition goes here + if (loopCount > 4) // for example + { + simulationComplete = true; + } + // your own simulation code is finished here! + // ============================================================================================= + + // keep track of timestep: wait duration for elapsed time in this loop + // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes + Thread.sleep((long)(LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds + System.out.println ("... Pausing for " + LOOP_DURATION_SECONDS + " seconds"); + + // send the status PDUs for this loop and continue + System.out.println ("sending PDUs for simulation step " + loopCount + ", monitor loopback to confirm sent"); + sendAllPdus(entityStatePdu, firePduNull, null, narrativeMessage1, narrativeMessage2, narrativeMessage3); + sendAllPdus(entityStatePdu2, null, null, narrativeMessage1, narrativeMessage2, narrativeMessage4); + System.out.println ("... PDUs successfully sent"); + + // =============================== + // loop now finished, thus terminate if simulation complete, otherwise send latest PDUs and continue + if (simulationComplete || (loopCount > 10000)) // for example; including fail-safe condition is good + { + System.out.println ("... Termination condition met, simulationComplete=" + simulationComplete); + break; + } + } // end of while loop + } + catch (Exception ex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(ExampleSimulationProgram.class.getName()).log(Level.SEVERE, null, ex); + } + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/PDUReciever.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/PDUReciever.java new file mode 100644 index 0000000000000000000000000000000000000000..5ab4c55cfd26e8629ba58a195b819a1c0d3c3fbe --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Britt/PDUReciever.java @@ -0,0 +1,128 @@ +package MV3500Cohort2020JulySeptember.homework4.White; + +import MV3500Cohort2020JulySeptember.homework4.White.working.*; +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; + +/** + * Receives PDUs from GermanyEspduReceiverEspduVPNSender in IEEE DIS format. + * + * @date 09/05/2020 + * @author Bernd/Stefan + * @version 0.1 + */ +public class PDUReciever { + + /** + * Max size of a PDU in binary format that we can receive. This is actually + * somewhat outdated--PDUs can be larger--but this is a reasonable starting + * point. + */ + public static final int MAX_PDU_SIZE = 8192; + + /** + * Default port used, matches Wireshark DIS capture default + */ + public static final int DEFAULT_PORT = 2317; + public static final int SECOND_PORT = 3000; + public static final int THIRD_PORT = 2318; + + + /** + * Output prefix to identify this class + */ + private final static String TRACE_PREFIX = "[" + PDUReciever.class.getName() + "] "; + + public static void main(String args[]) { + System.out.println(TRACE_PREFIX + "started..."); + + MulticastSocket socket1; + MulticastSocket socket2; + MulticastSocket socket3; + DatagramPacket packet; + DatagramPacket packet2; + DatagramPacket packet3; + PduFactory pduFactory = new PduFactory(); + ArrayList<EntityID> knownEntities = new ArrayList<EntityID>(); + int pduCount = 0; + + try { + // Specify the socket to receive data + socket1 = new MulticastSocket(DEFAULT_PORT); + socket2 = new MulticastSocket(SECOND_PORT); + socket3 = new MulticastSocket(THIRD_PORT); + + System.out.println(TRACE_PREFIX + "listening for PDU packets on port " + DEFAULT_PORT );//+ " " + SECOND_PORT + " " + THIRD_PORT); + System.out.println("===================================================="); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[MAX_PDU_SIZE]; + packet = new DatagramPacket(buffer, buffer.length); + + socket1.receive(packet); + + + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData(), packet.getLength()); + if (pduBundle.size() > 1) { // should be 1 for this project + System.out.println("Bundle size is " + pduBundle.size()); + } + + // end iterator loop through PDU bundle + for (Pdu aPdu : pduBundle) { + pduCount++; + String receiptMessage = String.format("%3s", pduCount) // right justify, 3 characters + + ". received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName() + " from " + packet.getAddress(); + if (aPdu instanceof EntityStatePdu) { + System.out.println(receiptMessage); + EntityID entityID = ((EntityStatePdu) aPdu).getEntityID(); + Vector3Double position = ((EntityStatePdu) aPdu).getEntityLocation(); + System.out.println(" entityID triplet: [" + entityID.getSiteID() + ", " + entityID.getApplicationID() + ", " + entityID.getEntityID() + "] "); + if (!knownEntities.contains(entityID)){ + knownEntities.add(entityID); + EntityType entityType = ((EntityStatePdu) aPdu).getEntityType(); + System.out.println(" New Entity: " +entityType.getEntityKind() + " "+ entityType.getDomain() + " "+ entityType.getCountry() + " "+ entityType.getCategory() + " "+ entityType.getSubCategory() + " "+ entityType.getSpecific() ); + } + System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + + } + else if (aPdu instanceof FirePdu){ + System.out.println(receiptMessage); + EntityID firingEntityID = ((FirePdu) aPdu).getFiringEntityID(); + EntityID targetEntityID = ((FirePdu) aPdu).getTargetEntityID(); + MunitionDescriptor munitionDescriptor = ((FirePdu) aPdu).getDescriptor(); + System.out.println(" firingEntityID triplet: [" + firingEntityID.getSiteID() + ", " + firingEntityID.getApplicationID() + ", " + firingEntityID.getEntityID() + "] "); + System.out.println(" targetEntityID triplet: [" + targetEntityID.getSiteID() + ", " + targetEntityID.getApplicationID() + ", " + targetEntityID.getEntityID() + "] "); + System.out.println(" Munition Information: [" + munitionDescriptor.getMunitionType().getDomain() + "."+munitionDescriptor.getMunitionType().getCountry() + "." + munitionDescriptor.getMunitionType().getCategory() + "."+ munitionDescriptor.getMunitionType().getSubCategory() + "." + munitionDescriptor.getMunitionType().getSpecific() + "]"); + } + else if (aPdu instanceof CommentReliablePdu){ + System.out.println(receiptMessage); + ArrayList<VariableDatum> payloadList = (ArrayList)((CommentReliablePdu) aPdu).getVariableDatumRecords(); + if (!payloadList.isEmpty()) + System.out.print (" messages: "); + for (VariableDatum variableDatum : payloadList) + { + String nextComment = new String(variableDatum.getVariableDatumValue()); // convert byte[] to String + System.out.print (" \"" + nextComment + "\""); + System.out.println(); + } + } //OTHER PDU TYPES + else { + System.out.println(receiptMessage); + } + } // end of bundle loop + + } // end of while loop + } // end try block // end try block // end try block // end try block + catch (IOException ioe) { + System.out.println(TRACE_PREFIX + "Problem with input/output, see exception trace:"); + System.out.println(ioe); + } + System.out.println(TRACE_PREFIX + "complete."); + } // end main +} // end class diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/CannonArtillerySimulation.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/CannonArtillerySimulation.java new file mode 100644 index 0000000000000000000000000000000000000000..cc43ae2fd99bc4f5bf3b6800a75011cefb7fbbcc --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/CannonArtillerySimulation.java @@ -0,0 +1,440 @@ +/** + * Copyright (c) 2008-2020, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package MV3500Cohort2020JulySeptember.homework4.Cannon; + +import MV3500Cohort2020JulySeptember.homework4.White.*; +import edu.nps.moves.dis7.enumerations.*; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class CannonArtillerySimulation { + + // class variables + PduFactory pduFactory = new PduFactory(); + DisThreadedNetworkInterface disNetworkInterface; + DisThreadedNetworkInterface.PduListener pduListener; + Pdu receivedPdu; + + private String networkAddress = "localhost";//"10.1.105.8"; + private int networkPort = 2317; + + /** + * Constructor design goal: additional built-in initialization conveniences + * can go here to keep student efforts focused on the runSimulation() + * method. + */ + public CannonArtillerySimulation() { + // Under consideration. Constructor is not currently needed. + } + + /** + * Utility Constructor + * + * @param address network address to use + * @param port corresponding network port to use + */ + public CannonArtillerySimulation(String address, int port) { + setNetworkAddress(address); + + setNetworkPort(port); + } + + /** + * @return the networkAddress + */ + public String getNetworkAddress() { + return networkAddress; + } + + /** + * @param networkAddress the networkAddress to set + */ + public final void setNetworkAddress(String networkAddress) { + this.networkAddress = networkAddress; + } + + /** + * @return the networkPort + */ + public int getNetworkPort() { + return networkPort; + } + + /** + * @param networkPort the networkPort to set + */ + public final void setNetworkPort(int networkPort) { + this.networkPort = networkPort; + } + + /** + * Initialize network interface, choosing best available network interface + */ + public void setUpNetworkInterface() { + disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); + + System.out.println("Network confirmation: address=" + disNetworkInterface.getMcastGroup() + " port=" + disNetworkInterface.getDisPort()); + pduListener = new DisThreadedNetworkInterface.PduListener() { + /** + * Callback handler for listener + */ + @Override + public void incomingPdu(Pdu newPdu) { + receivedPdu = newPdu; + } + }; + disNetworkInterface.addListener(pduListener); + } + + /** + * All done, release network resources + */ + public void tearDownNetworkInterface() { + disNetworkInterface.removeListener(pduListener); + disNetworkInterface.kill(); + disNetworkInterface = null; + } + + /** + * Send a single Protocol Data Unit (PDU) of any type + * + * @param pdu the pdu to send + */ + private void sendSinglePdu(Pdu pdu) { + try { + disNetworkInterface.send(pdu); + Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally + } catch (InterruptedException ex) { + System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); + System.exit(1); + } + } + + /** + * Send EntityState, Fire, Comment PDUs + * + * @see + * <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing + * Information to a Method or a Constructor</a> Arbitrary Number of + * Arguments + * @param entityStatePdu the ESPDU to send, if any + * @param firePdu the FirePDU to send, if any + * @param commentType enumeration value describing the narrative comment + * @param comments String array of narrative comments + */ + public void sendAllPdus(EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable length string + String... comments) { + if (entityStatePdu != null) { + sendSinglePdu(entityStatePdu); + } + + if (firePdu != null) { + sendSinglePdu(firePdu); // bang + } + if ((comments != null) && (comments.length > 0)) { + ArrayList<String> newCommentsList = new ArrayList<>(); + for (int i = 0; i < comments.length; i++) { + if (!comments[i].isEmpty()) { + newCommentsList.add(comments[i]); // OK found something to send + } + } + if (!newCommentsList.isEmpty()) { + if (commentType == null) { + commentType = VariableRecordType.OTHER; + } + CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); + sendSinglePdu(commentPdu); + } + } + } + + /** + * Main method is first executed when a program instance is loaded. + * + * @see + * <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java + * Tutorials: A Closer Look at the "Hello World!" Application</a> + * @param args command-line arguments are an array of optional String + * parameters that are passed from execution environment during invocation + */ + public static void main(String[] args) { + CannonArtillerySimulation thisProgram = new CannonArtillerySimulation(); // creates instance + + // initial execution: can handle args array of initialization arguments here + if (args.length == 2) { + if ((args[0] != null) && !args[0].isEmpty()) { + thisProgram.setNetworkAddress(args[0]); + } + + if ((args[1] != null) && !args[1].isEmpty()) { + thisProgram.setNetworkPort(Integer.parseInt(args[1])); + } + } else if (args.length != 0) { + System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); + System.exit(-1); + } + // OK here we go... + + //thisProgram.setUpNetworkInterface(); + thisProgram.runSimulation(); // customization code goes in there + + //thisProgram.tearDownNetworkInterface(); + } + + /** + * Programmer-modifiable method for defining and running a new simulation of + * interest. Support include DIS EntityStatePdu, FirePdu and CommentPdu all + * available for modification and sending in a simulation loop. + */ + @SuppressWarnings("SleepWhileInLoop") + public void runSimulation() { + try { + final double LOOP_DURATION_SECONDS = 1.0; // seconds + final int MAX_LOOP_COUNT = 10; + int loopCount = 0; + VariableRecordType narrativeType = VariableRecordType.OTHER; // of potential use + boolean simulationComplete = false; // sentinel variable as termination condition + boolean fireBool = false; + boolean destBool = false; + + // TODO reset clock to zero each time for consistent outputs. + // your model setup: who's who in this zoo? + // create PDU objects and set their values + //Vector3Double eloc3 = new Vector3Double(); + //double[] loc3 = CoordinateConversions.getXYZfromLatLonDegrees(36.6327591, -121.9232494, 0);//My house will be the firing location of the paladin. 36.6327591,-121.9232494,18.71z + EntityID entityID_1 = new EntityID(); + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID + + EntityStatePdu entityStatePdu = pduFactory.makeEntityStatePdu(); + entityStatePdu.setEntityID(entityID_1); + + EntityID paladinID = new EntityID(); + paladinID.setSiteID(2); + paladinID.setApplicationID(10); + paladinID.setEntityID(3); + entityStatePdu.setEntityID(paladinID); + EntityType paladinType = new EntityType(); //1.1.225.4.3.7 M109A6 Paladin (Self-proppelled howitzer) + paladinType.setEntityKind(EntityKind.PLATFORM); + paladinType.setDomain(Domain.inst(PlatformDomain.LAND)); + paladinType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + paladinType.setCategory(4); //4 + paladinType.setSubCategory(3); //3 + paladinType.setSpecific(7); //7 + + entityStatePdu.setEntityType(paladinType); + Vector3Double eloc2 = new Vector3Double(); + double[] loc2 = CoordinateConversions.getXYZfromLatLonDegrees(36.6327591, -121.9232494, 0);//My house will be the firing location of the paladin. 36.6327591,-121.9232494,18.71z + eloc2.setX(loc2[0]); + eloc2.setY(loc2[1]); + eloc2.setZ(loc2[2]); + entityStatePdu.setEntityLocation(eloc2); + EulerAngles orient2 = new EulerAngles(); + orient2.setPhi((float) 0.0); + orient2.setPsi((float) 0.0); + orient2.setTheta((float) 0.0); + entityStatePdu.setEntityOrientation(orient2); + + EntityStatePdu entityStatePdu2 = pduFactory.makeEntityStatePdu(); + + EntityID bmpID = new EntityID(); + bmpID.setSiteID(1); + bmpID.setApplicationID(13); + bmpID.setEntityID(2); + entityStatePdu2.setEntityID(bmpID); + EntityType bmpType = new EntityType(); //1.1.222.2.2.1 Platform,Ground,Russia,ArmoredFightingVehicle,BMP2,BMP2 + bmpType.setEntityKind(EntityKind.PLATFORM); + bmpType.setDomain(Domain.inst(PlatformDomain.LAND)); + bmpType.setCountry(Country.RUSSIA); + bmpType.setCategory(2); + bmpType.setSubCategory(41); + bmpType.setSpecific(3); + entityStatePdu2.setEntityType(bmpType); + Vector3Double eloc1 = new Vector3Double(); + double[] loc1 = CoordinateConversions.getXYZfromLatLonDegrees(36.594116, -121.877463, 0); //NPS Main Gate + eloc1.setX(loc1[0]); + eloc1.setY(loc1[1]); + eloc1.setZ(loc1[2]); + + entityStatePdu2.setEntityLocation(eloc1); + EulerAngles orient1 = new EulerAngles(); + orient1.setPhi((float) 0.0); + orient1.setPsi((float) 0.0); + orient1.setTheta((float) 0.0); + entityStatePdu2.setEntityOrientation(orient1); + + int BMPHitsReceived = 0; + System.out.println("Firing Position Location"); + System.out.println(eloc2.toString()); + System.out.println("****************"); + System.out.println("BMP Location"); + System.out.println(eloc1.toString()); + + //FirePdu firePduNull = new FirePdu(); + FirePdu firePdu = pduFactory.makeFirePdu(); + EntityID fireID = new EntityID(); + fireID.setSiteID(2); + fireID.setApplicationID(10); + fireID.setEntityID(3); + EntityID targetID = new EntityID(); + targetID.setSiteID(1); + targetID.setApplicationID(13); + targetID.setEntityID(2); + + firePdu.setFiringEntityID(fireID); + firePdu.setTargetEntityID(targetID); + + EntityType HEType = new EntityType(); //2.9.225.2.14.20.2 HE 795 W/ PD FUZE + HEType.setEntityKind(EntityKind.MUNITION); + HEType.setDomain(Domain.inst(PlatformDomain.AIR)); + HEType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + HEType.setCategory(2); //HE is 2 + HEType.setSubCategory(14); //14 + HEType.setSpecific(1); //20 + HEType.setExtra(2); //HE PD + MunitionDescriptor HEIT = new MunitionDescriptor(); + HEIT.setMunitionType(HEType); + HEIT.setQuantity(6); + HEIT.setFuse(MunitionDescriptorFuse.CONTACT_GRAZE); + HEIT.setRate(600); + firePdu.setDescriptor(HEIT); + EntityID HEID = new EntityID(); + HEID.setEntityID(1); + firePdu.setMunitionExpendibleID(HEID); + + Double dx = eloc2.getX() - eloc1.getX(); + Double dy = eloc2.getY() - eloc1.getY(); + Double range = Math.sqrt(dx * dx + dy * dy); + System.out.println("THE M109A6 PALADIN WILL FIRE 6 VOLLEYS OF HE/PD USING CHARGE 1L FOR DISTANCE OF " + range + " METERS AT HIGH ANGLE"); + + CommentReliablePdu bmpDestroyedComment = pduFactory.makeCommentReliablePdu("BMP2 DESTROYED BY M109A6 AFTER SIX VOLLEYS OF HE/PD ON TARGET"); + while (loopCount < MAX_LOOP_COUNT) // loop the simulation while allowed, can set additional conditions to break + { + String narrativeMessage1, narrativeMessage2, narrativeMessage3, narrativeMessage4; + narrativeMessage4 = ""; + // initialize loop variables + loopCount++; + + // ============================================================================================= + // your own simulation code starts here! + // compute a track, update an ESPDU, whatever it is that your model is doing... + // Where is my entity? + + System.out.println("Entity#" + firePdu.getFiringEntityID().getEntityID() + " is firing " + + firePdu.getDescriptor().getMunitionType().getDomain() + "." + firePdu.getDescriptor().getMunitionType().getCountry() + + "." + firePdu.getDescriptor().getMunitionType().getCategory() + "." + firePdu.getDescriptor().getMunitionType().getSubCategory() + + "." + firePdu.getDescriptor().getMunitionType().getSpecific() + "." + firePdu.getDescriptor().getMunitionType().getExtra() + "." + "at Entity#" + firePdu.getTargetEntityID().getEntityID()); + fireBool = true; + if (firePdu.getTargetEntityID().getEntityID() == 2) { + BMPHitsReceived += 1; + if (BMPHitsReceived > 5) { + //DESTROY THE BMP! + + System.out.println("BMP Destroyed after " + BMPHitsReceived + " hits from 155mm Indirect Fire"); + narrativeMessage4 = "Destroyed BMP2"; + destBool = true; + } + } + + // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) + narrativeMessage1 = "MV3500 ExampleSimulationProgram"; + narrativeMessage2 = "runSimulation() loop " + loopCount; + narrativeMessage3 = "M109A6 Paladin"; // intentionally blank for testing + if (narrativeMessage4.isEmpty()) { + narrativeMessage4 = "BMP2"; + } + // your loop termination condition goes here + if (loopCount > 5) // for example + { + simulationComplete = true; + } + // your own simulation code is finished here! + // ============================================================================================= + + // keep track of timestep: wait duration for elapsed time in this loop + // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes + Thread.sleep((long) (LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds + System.out.println("... Pausing for " + LOOP_DURATION_SECONDS + " seconds"); + + // send the status PDUs for this loop and continue + System.out.println("sending PDUs for simulation step " + loopCount + ", monitor loopback to confirm sent"); + //sendAllPdus(entityStatePdu, firePduNull, null, narrativeMessage1, narrativeMessage2, narrativeMessage3); + //sendAllPdus(entityStatePdu2, null, null, narrativeMessage1, narrativeMessage2, narrativeMessage4); + sendPDU(entityStatePdu); + sendPDU(entityStatePdu2); + if (fireBool) { + sendPDU(firePdu); + } + if (destBool) { + sendPDU(bmpDestroyedComment); + } + System.out.println("... PDUs successfully sent"); + + // =============================== + // loop now finished, thus terminate if simulation complete, otherwise send latest PDUs and continue + if (simulationComplete || (loopCount > 10000)) // for example; including fail-safe condition is good + { + CommentReliablePdu completionPdu = pduFactory.makeCommentReliablePdu("Cannon Simulation Completed"); + sendPDU(completionPdu); + System.out.println("... Termination condition met, simulationComplete=" + simulationComplete); + break; + } + } // end of while loop + } catch (Exception ex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(CannonArtillerySimulation.class.getName()).log(Level.SEVERE, null, ex); + } + + } + + public void sendPDU(Pdu pdu) { + System.out.println("Sending a PDU"); + MulticastSocket socket = null; // must be initialized, even if null + InetAddress destinationIp = null; // must be initialized, even if null + + try { + destinationIp = InetAddress.getByName(networkAddress); + } catch (UnknownHostException e) { + System.out.println(e + " Cannot create address"); + System.exit(0); + } + try { + // Set up a socket to send information + socket = new MulticastSocket(2317); + } catch (IOException ex) { + Logger.getLogger(MV3500Cohort2020JulySeptember.homework4.White.working.WhiteSimulation.class.getName()).log(Level.SEVERE, null, ex); + } + + Set<InetAddress> broadcastAddresses; + // Loop through sending one ESPDUs + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + try { + pdu.marshal(dos); + byte[] data = baos.toByteArray(); + + DatagramPacket packet = new DatagramPacket(data, data.length, destinationIp, 2317); + socket.send(packet); + socket.close(); + } catch (Exception ex) { + Logger.getLogger(MV3500Cohort2020JulySeptember.homework4.White.working.WhiteSimulation.class.getName()).log(Level.SEVERE, null, ex); + } + } + +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/CannonOutputLog.md b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/CannonOutputLog.md new file mode 100644 index 0000000000000000000000000000000000000000..3645bf9e062f9f972aa1218b248ab73c40c09f28 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/CannonOutputLog.md @@ -0,0 +1,69 @@ +[MV3500Cohort2020JulySeptember.homework4.Cannon.PDUReciever] started... +[MV3500Cohort2020JulySeptember.homework4.Cannon.PDUReciever] listening for PDU packets on port 2317 +==================================================== + 1. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [2, 10, 3] + New Entity: EntityKind 1 PLATFORM Land Country 225 UNITED_STATES_OF_AMERICA_USA 4 3 7 + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 2. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [1, 13, 2] + New Entity: EntityKind 1 PLATFORM Land Country 260 RUSSIA 2 41 3 + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 3. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /127.0.0.1 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1.2] + 4. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 5. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 6. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /127.0.0.1 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1.2] + 7. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 8. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 9. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /127.0.0.1 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1.2] + 10. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 11. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 12. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /127.0.0.1 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1.2] + 13. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 14. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 15. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /127.0.0.1 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1.2] + 16. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 17. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /127.0.0.1 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 18. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /127.0.0.1 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1.2] + 19. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /127.0.0.1 + messages: "BMP2 DESTROYED BY M109A6 AFTER SIX VOLLEYS OF HE/PD ON TARGET" + 20. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /127.0.0.1 + messages: "Cannon Simulation Completed" \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/PDUReciever.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/PDUReciever.java new file mode 100755 index 0000000000000000000000000000000000000000..6a601f054ecbf0077a875085a05f2df6b1b654d1 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Cannon/PDUReciever.java @@ -0,0 +1,128 @@ +package MV3500Cohort2020JulySeptember.homework4.Cannon; + +import MV3500Cohort2020JulySeptember.homework4.White.working.*; +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; + +/** + * Receives PDUs from GermanyEspduReceiverEspduVPNSender in IEEE DIS format. + * + * @date 09/05/2020 + * @author Bernd/Stefan + * @version 0.1 + */ +public class PDUReciever { + + /** + * Max size of a PDU in binary format that we can receive. This is actually + * somewhat outdated--PDUs can be larger--but this is a reasonable starting + * point. + */ + public static final int MAX_PDU_SIZE = 8192; + + /** + * Default port used, matches Wireshark DIS capture default + */ + public static final int DEFAULT_PORT = 2317; + public static final int SECOND_PORT = 3000; + public static final int THIRD_PORT = 2318; + + + /** + * Output prefix to identify this class + */ + private final static String TRACE_PREFIX = "[" + PDUReciever.class.getName() + "] "; + + public static void main(String args[]) { + System.out.println(TRACE_PREFIX + "started..."); + + MulticastSocket socket1; + MulticastSocket socket2; + MulticastSocket socket3; + DatagramPacket packet; + DatagramPacket packet2; + DatagramPacket packet3; + PduFactory pduFactory = new PduFactory(); + ArrayList<EntityID> knownEntities = new ArrayList<EntityID>(); + int pduCount = 0; + + try { + // Specify the socket to receive data + socket1 = new MulticastSocket(DEFAULT_PORT); + socket2 = new MulticastSocket(SECOND_PORT); + socket3 = new MulticastSocket(THIRD_PORT); + + System.out.println(TRACE_PREFIX + "listening for PDU packets on port " + DEFAULT_PORT );//+ " " + SECOND_PORT + " " + THIRD_PORT); + System.out.println("===================================================="); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[MAX_PDU_SIZE]; + packet = new DatagramPacket(buffer, buffer.length); + + socket1.receive(packet); + + + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData(), packet.getLength()); + if (pduBundle.size() > 1) { // should be 1 for this project + System.out.println("Bundle size is " + pduBundle.size()); + } + + // end iterator loop through PDU bundle + for (Pdu aPdu : pduBundle) { + pduCount++; + String receiptMessage = String.format("%3s", pduCount) // right justify, 3 characters + + ". received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName() + " from " + packet.getAddress(); + if (aPdu instanceof EntityStatePdu) { + System.out.println(receiptMessage); + EntityID entityID = ((EntityStatePdu) aPdu).getEntityID(); + Vector3Double position = ((EntityStatePdu) aPdu).getEntityLocation(); + System.out.println(" entityID triplet: [" + entityID.getSiteID() + ", " + entityID.getApplicationID() + ", " + entityID.getEntityID() + "] "); + if (!knownEntities.contains(entityID)){ + knownEntities.add(entityID); + EntityType entityType = ((EntityStatePdu) aPdu).getEntityType(); + System.out.println(" New Entity: " +entityType.getEntityKind() + " "+ entityType.getDomain() + " "+ entityType.getCountry() + " "+ entityType.getCategory() + " "+ entityType.getSubCategory() + " "+ entityType.getSpecific() ); + } + System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + + } + else if (aPdu instanceof FirePdu){ + System.out.println(receiptMessage); + EntityID firingEntityID = ((FirePdu) aPdu).getFiringEntityID(); + EntityID targetEntityID = ((FirePdu) aPdu).getTargetEntityID(); + MunitionDescriptor munitionDescriptor = ((FirePdu) aPdu).getDescriptor(); + System.out.println(" firingEntityID triplet: [" + firingEntityID.getSiteID() + ", " + firingEntityID.getApplicationID() + ", " + firingEntityID.getEntityID() + "] "); + System.out.println(" targetEntityID triplet: [" + targetEntityID.getSiteID() + ", " + targetEntityID.getApplicationID() + ", " + targetEntityID.getEntityID() + "] "); + System.out.println(" Munition Information: [" + munitionDescriptor.getMunitionType().getDomain() + "."+munitionDescriptor.getMunitionType().getCountry() + "." + munitionDescriptor.getMunitionType().getCategory() + "."+ munitionDescriptor.getMunitionType().getSubCategory() + "." + munitionDescriptor.getMunitionType().getSpecific() + "." + munitionDescriptor.getMunitionType().getExtra() + "]"); + } + else if (aPdu instanceof CommentReliablePdu){ + System.out.println(receiptMessage); + ArrayList<VariableDatum> payloadList = (ArrayList)((CommentReliablePdu) aPdu).getVariableDatumRecords(); + if (!payloadList.isEmpty()) + System.out.print (" messages: "); + for (VariableDatum variableDatum : payloadList) + { + String nextComment = new String(variableDatum.getVariableDatumValue()); // convert byte[] to String + System.out.print (" \"" + nextComment + "\""); + System.out.println(); + } + } //OTHER PDU TYPES + else { + System.out.println(receiptMessage); + } + } // end of bundle loop + + } // end of while loop + } // end try block // end try block // end try block // end try block + catch (IOException ioe) { + System.out.println(TRACE_PREFIX + "Problem with input/output, see exception trace:"); + System.out.println(ioe); + } + System.out.println(TRACE_PREFIX + "complete."); + } // end main +} // end class diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Mahan/Final Project SISO IEEE addition.pptx b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Mahan/Final Project SISO IEEE addition.pptx new file mode 100644 index 0000000000000000000000000000000000000000..a1da86da2045b7810be06359e18811674bcb7897 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Mahan/Final Project SISO IEEE addition.pptx differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Weissenberger/README.md b/assignments/src/MV3500Cohort2020JulySeptember/homework4/Weissenberger/README.md deleted file mode 100644 index 0144d62d033fbe094ceac7a6d1bedc12d3c158b0..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Weissenberger/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## Homework 2: Multicast Networking - -Modify this file to describe your project work. - -Typical deliverables include properly packages source, execution log, and screen shots as appropriate. - -References include -* [README.md](../README.md) for this homework project. -* [README.md](../../../../README.md) for course assignments execution instructions. -* [assignments source subdirectories](../../../../../assignments/src) show examples from previous cohorts. - -Questions and innovation are always welcome, good luck! diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/.gitkeep b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/2020-09-11-15-31-14.mp4 b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/2020-09-11-15-31-14.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..a32bd83208fba4f8034f793f09c427cfedb287be Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/2020-09-11-15-31-14.mp4 differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/Android2WindowsDIS.pcapng b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/Android2WindowsDIS.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..a99f1cd5bfcabb0125366ee1fee365575939ed68 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/Android2WindowsDIS.pcapng differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/FinalPresentation.pptx b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/FinalPresentation.pptx new file mode 100644 index 0000000000000000000000000000000000000000..81d7f35bd41a3468809da52006f22f3f0c7dee9c Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/FinalPresentation.pptx differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/FinalProject.pdf b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/FinalProject.pdf new file mode 100644 index 0000000000000000000000000000000000000000..700924997ef1e6cc6aeaa1dd7ee2106528a2ec21 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/FinalProject.pdf differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/GermanyEspduReceiverEspduVPNSender.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/GermanyEspduReceiverEspduVPNSender.java new file mode 100755 index 0000000000000000000000000000000000000000..21e958d84e48e335fc9c9408a2520314cea12f12 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/GermanyEspduReceiverEspduVPNSender.java @@ -0,0 +1,135 @@ +package MV3500Cohort2020JulySeptember.homework4.WeissenbergerGoericke; + +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Receives PDUs from mobile devise in IEEE DIS format. Send it over VPN (argon) + * to Stefan's PDU Receiver + * + * @date 09/05/2020 + * @author Bernd/Stefan + * @version 0.1 + */ +public class GermanyEspduReceiverEspduVPNSender { + + /** + * Stefan's IP in argon + */ + public static final String VPN_RECEIVER_ADDRESS = "10.1.105.10"; + + /** + * Max size of a PDU in binary format that we can receive. This is actually + * somewhat outdated--PDUs can be larger--but this is a reasonable starting + * point. + */ + public static final int MAX_PDU_SIZE = 8192; + + /** + * Default port used, matches Wireshark DIS capture default + */ + public static final int DEFAULT_PORT = 3000; + + /** + * Output prefix to identify this class + */ + private final static String TRACE_PREFIX = "[" + GermanyEspduVPNReceiver.class.getName() + "] "; + + public static void main(String args[]) { + System.out.println(TRACE_PREFIX + "started..."); + + MulticastSocket socket; + DatagramPacket packet; + PduFactory pduFactory = new PduFactory(); + int pduCount = 0; + + try { + // Specify the socket to receive data + socket = new MulticastSocket(DEFAULT_PORT); + + + + System.out.println(TRACE_PREFIX + "listening for PDU packets on port " + DEFAULT_PORT); + System.out.println("==============="); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[MAX_PDU_SIZE]; + packet = new DatagramPacket(buffer, buffer.length); + + socket.receive(packet); + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData(), packet.getLength()); + if (pduBundle.size() > 1) { + System.out.println("Bundle size is " + pduBundle.size()); + } + + // end iterator loop through PDU bundle + for (Pdu aPdu : pduBundle) { + pduCount++; + String receiptMessage = String.format("%3s", pduCount) // right justify, 3 characters + + ". received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName(); + // only handle ESPDU at this point (no fire PDU etc...) + if (aPdu instanceof EntityStatePdu) { + System.out.println(receiptMessage); + EntityID entityID = ((EntityStatePdu) aPdu).getEntityID(); + Vector3Double position = ((EntityStatePdu) aPdu).getEntityLocation(); + System.out.println(" entityID triplet: [" + entityID.getSiteID() + ", " + entityID.getApplicationID() + ", " + entityID.getEntityID() + "] "); + System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + sendESPDU((EntityStatePdu) aPdu); + }else { + System.out.println(receiptMessage); + } + + } // end of bundle loop + } // end of while loop + } // end try block // end try block // end try block // end try block + catch (IOException ioe) { + System.out.println(TRACE_PREFIX + "Problem with input/output, see exception trace:"); + System.out.println(ioe); + } + System.out.println(TRACE_PREFIX + "complete."); + } // end main + + /** + * gets the espdu from main and send it to VPN_RECEIVER_ADDRESS + * @param espdu + */ + public static void sendESPDU(EntityStatePdu espdu) { + MulticastSocket socket = null; // must be initialized, even if null + InetAddress destinationIp = null; // must be initialized, even if null + + try { + destinationIp = InetAddress.getByName(VPN_RECEIVER_ADDRESS); + } catch (UnknownHostException e) { + System.out.println(e + " Cannot create address"); + System.exit(0); + } + try { + // Set up a socket to send information + socket = new MulticastSocket(DEFAULT_PORT); + } catch (IOException ex) { + Logger.getLogger(GermanyEspduReceiverEspduVPNSender.class.getName()).log(Level.SEVERE, null, ex); + } + + Set<InetAddress> broadcastAddresses; + // Loop through sending one ESPDUs + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + try { + espdu.marshal(dos); + byte[] data = baos.toByteArray(); + + DatagramPacket packet = new DatagramPacket(data, data.length, destinationIp, DEFAULT_PORT); + socket.send(packet); + } catch (Exception ex) { + Logger.getLogger(GermanyEspduReceiverEspduVPNSender.class.getName()).log(Level.SEVERE, null, ex); + } + } // end sendESPDU +} // end class diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/GermanyEspduVPNReceiver.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/GermanyEspduVPNReceiver.java new file mode 100755 index 0000000000000000000000000000000000000000..9da81fe9bcd97b46abf0d5ab5b4a4a126cc7b62d --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/GermanyEspduVPNReceiver.java @@ -0,0 +1,86 @@ +package MV3500Cohort2020JulySeptember.homework4.WeissenbergerGoericke; + +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; + +/** + * Receives PDUs from GermanyEspduReceiverEspduVPNSender in IEEE DIS format. + * + * @date 09/05/2020 + * @author Bernd/Stefan + * @version 0.1 + */ +public class GermanyEspduVPNReceiver { + + /** + * Max size of a PDU in binary format that we can receive. This is actually + * somewhat outdated--PDUs can be larger--but this is a reasonable starting + * point. + */ + public static final int MAX_PDU_SIZE = 8192; + + /** + * Default port used, matches Wireshark DIS capture default + */ + public static final int DEFAULT_PORT = 3000; + + /** + * Output prefix to identify this class + */ + private final static String TRACE_PREFIX = "[" + GermanyEspduVPNReceiver.class.getName() + "] "; + + public static void main(String args[]) { + System.out.println(TRACE_PREFIX + "started..."); + + MulticastSocket socket; + DatagramPacket packet; + PduFactory pduFactory = new PduFactory(); + int pduCount = 0; + + try { + // Specify the socket to receive data + socket = new MulticastSocket(DEFAULT_PORT); + + System.out.println(TRACE_PREFIX + "listening for PDU packets on port " + DEFAULT_PORT); + System.out.println("===================================================="); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[MAX_PDU_SIZE]; + packet = new DatagramPacket(buffer, buffer.length); + + socket.receive(packet); + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData(), packet.getLength()); + if (pduBundle.size() > 1) { // should be 1 for this project + System.out.println("Bundle size is " + pduBundle.size()); + } + + // end iterator loop through PDU bundle + for (Pdu aPdu : pduBundle) { + pduCount++; + String receiptMessage = String.format("%3s", pduCount) // right justify, 3 characters + + ". received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName(); + if (aPdu instanceof EntityStatePdu) { + System.out.println(receiptMessage); + EntityID entityID = ((EntityStatePdu) aPdu).getEntityID(); + Vector3Double position = ((EntityStatePdu) aPdu).getEntityLocation(); + System.out.println(" entityID triplet: [" + entityID.getSiteID() + ", " + entityID.getApplicationID() + ", " + entityID.getEntityID() + "] "); + System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + }else { + System.out.println(receiptMessage); + } + } // end of bundle loop + } // end of while loop + } // end try block // end try block // end try block // end try block + catch (IOException ioe) { + System.out.println(TRACE_PREFIX + "Problem with input/output, see exception trace:"); + System.out.println(ioe); + } + System.out.println(TRACE_PREFIX + "complete."); + } // end main +} // end class diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/ProjectAndroidApp.zip b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/ProjectAndroidApp.zip new file mode 100644 index 0000000000000000000000000000000000000000..ce586cbd06b30dd656bcf7254dec39e0d84937c2 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/ProjectAndroidApp.zip differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/ProjectIdeaTeamGermany.jpg b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/ProjectIdeaTeamGermany.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2a9ac8e61fabb4a80973264378387b23cd334733 Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/ProjectIdeaTeamGermany.jpg differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/Goericke/README.md b/assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/README.md similarity index 100% rename from assignments/src/MV3500Cohort2020JulySeptember/homework4/Goericke/README.md rename to assignments/src/MV3500Cohort2020JulySeptember/homework4/WeissenbergerGoericke/README.md diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/README.md b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/README.md deleted file mode 100644 index 0144d62d033fbe094ceac7a6d1bedc12d3c158b0..0000000000000000000000000000000000000000 --- a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## Homework 2: Multicast Networking - -Modify this file to describe your project work. - -Typical deliverables include properly packages source, execution log, and screen shots as appropriate. - -References include -* [README.md](../README.md) for this homework project. -* [README.md](../../../../README.md) for course assignments execution instructions. -* [assignments source subdirectories](../../../../../assignments/src) show examples from previous cohorts. - -Questions and innovation are always welcome, good luck! diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/Receiver Output Log.md b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/Receiver Output Log.md new file mode 100644 index 0000000000000000000000000000000000000000..28edf57d003aa1f8405a0830f5680c0155e45e44 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/Receiver Output Log.md @@ -0,0 +1,149 @@ +[MV3500Cohort2020JulySeptember.homework4.White.working.PDUReciever] started... +[MV3500Cohort2020JulySeptember.homework4.White.working.PDUReciever] listening for PDU packets on port 2317 +==================================================== + 1. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 26] + New Entity: EntityKind 1 PLATFORM Land Country 225 UNITED_STATES_OF_AMERICA_USA 7 39 3 + Location in DIS coordinates: [-2707501.7340396782, -4353408.810297934, 3781834.0645668795] + 2. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 26] + Location in DIS coordinates: [-2707521.7340396782, -4353483.810297934, 3781834.0645668795] + 3. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 25] + New Entity: EntityKind 1 PLATFORM Land Country 225 UNITED_STATES_OF_AMERICA_USA 2 41 3 + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 4. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 26] + Location in DIS coordinates: [-2707541.7340396782, -4353558.810297934, 3781834.0645668795] + 5. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 25] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 6. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /10.1.105.11 + messages: "LAV25-A2 IS WITHIN DISTANCE OF RESUPPLY" + 7. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 26] + Location in DIS coordinates: [-2707561.7340396782, -4353633.810297934, 3781834.0645668795] + 8. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 25] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 9. received PDU type 6=RESUPPLY_OFFER edu.nps.moves.dis7.pdus.ResupplyOfferPdu from /10.1.105.11 + Resupply Offer from Entity [1, 13, 26] to resupply Entity [1, 13, 25] + Supplies Offered: [Quantity: 500.0, Type: EntityKind 2 MUNITION Air Country 225 UNITED_STATES_OF_AMERICA_USA 2 2 1 ] + 10. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 26] + Location in DIS coordinates: [-2707581.7340396782, -4353708.810297934, 3781834.0645668795] + 11. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.11 + entityID triplet: [1, 13, 25] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 12. received PDU type 6=RESUPPLY_OFFER edu.nps.moves.dis7.pdus.ResupplyOfferPdu from /10.1.105.11 + Resupply Offer from Entity [1, 13, 26] to resupply Entity [1, 13, 25] + Supplies Offered: [Quantity: 500.0, Type: EntityKind 2 MUNITION Air Country 225 UNITED_STATES_OF_AMERICA_USA 2 2 1 ] + 13. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /10.1.105.11 + messages: "Britt Simulation Completed" + 14. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [2, 10, 3] + New Entity: EntityKind 1 PLATFORM Land Country 225 UNITED_STATES_OF_AMERICA_USA 4 3 7 + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 15. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [1, 13, 2] + New Entity: EntityKind 1 PLATFORM Land Country 260 RUSSIA 2 41 3 + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 16. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /10.1.105.8 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1] + 17. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 18. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 19. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /10.1.105.8 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1] + 20. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 21. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 22. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /10.1.105.8 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1] + 23. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 24. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 25. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /10.1.105.8 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1] + 26. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 27. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 28. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /10.1.105.8 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1] + 29. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [2, 10, 3] + Location in DIS coordinates: [-2709702.5301454174, -4349384.2159421, 3784766.9772485564] + 30. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.8 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 31. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /10.1.105.8 + firingEntityID triplet: [2, 10, 3] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.14.1] + 32. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /10.1.105.8 + messages: "BMP2 DESTROYED BY M109A6 AFTER SIX VOLLEYS OF HE/PD ON TARGET" + 33. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /10.1.105.8 + messages: "Cannon Simulation Completed" + 34. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 25] + Location in DIS coordinates: [-2707501.7340396782, -4353408.810297934, 3781834.0645668795] + 35. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 25] + Location in DIS coordinates: [-2707521.7340396782, -4353483.810297934, 3781834.0645668795] + 36. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 37. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 25] + Location in DIS coordinates: [-2707541.7340396782, -4353558.810297934, 3781834.0645668795] + 38. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 39. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /10.1.105.7 + messages: "LAV25-A2 ACQUIRES TARGET BMP2 WITHIN FIRING DISTANCE" + 40. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 25] + Location in DIS coordinates: [-2707561.7340396782, -4353633.810297934, 3781834.0645668795] + 41. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 42. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /10.1.105.7 + firingEntityID triplet: [1, 13, 25] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.2.1] + 43. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 25] + Location in DIS coordinates: [-2707581.7340396782, -4353708.810297934, 3781834.0645668795] + 44. received PDU type 1=ENTITY_STATE edu.nps.moves.dis7.pdus.EntityStatePdu from /10.1.105.7 + entityID triplet: [1, 13, 2] + Location in DIS coordinates: [-2707576.630668249, -4353720.04383471, 3781324.902449432] + 45. received PDU type 2=FIRE edu.nps.moves.dis7.pdus.FirePdu from /10.1.105.7 + firingEntityID triplet: [1, 13, 25] + targetEntityID triplet: [1, 13, 2] + Munition Information: [Air.Country 225 UNITED_STATES_OF_AMERICA_USA.2.2.1] + 46. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /10.1.105.7 + messages: "BMP2 DESTROYED BY LAV25-A2 AFTER TWO BURSTS OF 25mm HEI-T ON TARGET" + 47. received PDU type 62=COMMENT_RELIABLE edu.nps.moves.dis7.pdus.CommentReliablePdu from /10.1.105.7 + messages: "White Simulation Completed" \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/WhiteCannonBritt.pptx b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/WhiteCannonBritt.pptx new file mode 100644 index 0000000000000000000000000000000000000000..234660d271475dee6a8c08b30ee2a61db630be0a Binary files /dev/null and b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/WhiteCannonBritt.pptx differ diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/test/PDUReciever.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/test/PDUReciever.java new file mode 100755 index 0000000000000000000000000000000000000000..7e586acc7965d1b4f1fa37a0982425a8c7a6d22a --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/test/PDUReciever.java @@ -0,0 +1,144 @@ +package MV3500Cohort2020JulySeptember.homework4.White.test; + +import MV3500Cohort2020JulySeptember.homework4.White.working.*; +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; + +/** + * Receives PDUs from GermanyEspduReceiverEspduVPNSender in IEEE DIS format. + * + * @date 09/05/2020 + * @author Bernd/Stefan + * @version 0.1 + */ +public class PDUReciever { + + /** + * Max size of a PDU in binary format that we can receive. This is actually + * somewhat outdated--PDUs can be larger--but this is a reasonable starting + * point. + */ + public static final int MAX_PDU_SIZE = 8192; + + /** + * Default port used, matches Wireshark DIS capture default + */ + public static final int DEFAULT_PORT = 2317; + public static final int SECOND_PORT = 3000; + public static final int THIRD_PORT = 2318; + + + /** + * Output prefix to identify this class + */ + private final static String TRACE_PREFIX = "[" + PDUReciever.class.getName() + "] "; + + public static void main(String args[]) { + System.out.println(TRACE_PREFIX + "started..."); + + MulticastSocket socket1; + MulticastSocket socket2; + MulticastSocket socket3; + DatagramPacket packet; + DatagramPacket packet2; + DatagramPacket packet3; + PduFactory pduFactory = new PduFactory(); + ArrayList<EntityID> knownEntities = new ArrayList<EntityID>(); + int pduCount = 0; + + try { + // Specify the socket to receive data + socket1 = new MulticastSocket(DEFAULT_PORT); + socket2 = new MulticastSocket(SECOND_PORT); + socket3 = new MulticastSocket(THIRD_PORT); + + System.out.println(TRACE_PREFIX + "listening for PDU packets on port " + DEFAULT_PORT );//+ " " + SECOND_PORT + " " + THIRD_PORT); + System.out.println("===================================================="); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[MAX_PDU_SIZE]; + packet = new DatagramPacket(buffer, buffer.length); + + socket1.receive(packet); + + + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData(), packet.getLength()); + if (pduBundle.size() > 1) { // should be 1 for this project + System.out.println("Bundle size is " + pduBundle.size()); + } + + // end iterator loop through PDU bundle + for (Pdu aPdu : pduBundle) { + pduCount++; + String receiptMessage = String.format("%3s", pduCount) // right justify, 3 characters + + ". received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName() + " from " + packet.getAddress(); + if (aPdu instanceof EntityStatePdu) { + System.out.println(receiptMessage); + EntityID entityID = ((EntityStatePdu) aPdu).getEntityID(); + Vector3Double position = ((EntityStatePdu) aPdu).getEntityLocation(); + System.out.println(" entityID triplet: [" + entityID.getSiteID() + ", " + entityID.getApplicationID() + ", " + entityID.getEntityID() + "] "); + if (!knownEntities.contains(entityID)){ + knownEntities.add(entityID); + EntityType entityType = ((EntityStatePdu) aPdu).getEntityType(); + System.out.println(" New Entity: " +entityType.getEntityKind() + " "+ entityType.getDomain() + " "+ entityType.getCountry() + " "+ entityType.getCategory() + " "+ entityType.getSubCategory() + " "+ entityType.getSpecific() ); + } + System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + + } + else if (aPdu instanceof FirePdu){ + System.out.println(receiptMessage); + EntityID firingEntityID = ((FirePdu) aPdu).getFiringEntityID(); + EntityID targetEntityID = ((FirePdu) aPdu).getTargetEntityID(); + MunitionDescriptor munitionDescriptor = ((FirePdu) aPdu).getDescriptor(); + System.out.println(" firingEntityID triplet: [" + firingEntityID.getSiteID() + ", " + firingEntityID.getApplicationID() + ", " + firingEntityID.getEntityID() + "] "); + System.out.println(" targetEntityID triplet: [" + targetEntityID.getSiteID() + ", " + targetEntityID.getApplicationID() + ", " + targetEntityID.getEntityID() + "] "); + System.out.println(" Munition Information: [" + munitionDescriptor.getMunitionType().getDomain() + "."+munitionDescriptor.getMunitionType().getCountry() + "." + munitionDescriptor.getMunitionType().getCategory() + "."+ munitionDescriptor.getMunitionType().getSubCategory() + "." + munitionDescriptor.getMunitionType().getSpecific() + "]"); + } + else if (aPdu instanceof CommentReliablePdu){ + System.out.println(receiptMessage); + ArrayList<VariableDatum> payloadList = (ArrayList)((CommentReliablePdu) aPdu).getVariableDatumRecords(); + if (!payloadList.isEmpty()) + System.out.print (" messages: "); + for (VariableDatum variableDatum : payloadList) + { + String nextComment = new String(variableDatum.getVariableDatumValue()); // convert byte[] to String + System.out.print (" \"" + nextComment + "\""); + System.out.println(); + }// + } + else if (aPdu instanceof ResupplyOfferPdu){ + System.out.println(receiptMessage); + EntityID receiverID = ((ResupplyOfferPdu) aPdu).getReceivingEntityID(); + EntityID supplierID = ((ResupplyOfferPdu) aPdu).getSupplyingEntityID(); + List<SupplyQuantity> supplyList = ((ResupplyOfferPdu) aPdu).getSupplies(); + System.out.println(" Resupply Offer from Entity [" + supplierID.getSiteID() + ", "+ supplierID.getApplicationID() + ", " + supplierID.getEntityID() + "] to resupply Entity ["+ receiverID.getSiteID() + ", "+ receiverID.getApplicationID() + ", " + receiverID.getEntityID() + "]" ); + for (int i = 0; i < supplyList.size(); i++){ + SupplyQuantity supplyQ = supplyList.get(i); + EntityType entityType = supplyQ.getSupplyType(); + float supplyQuantity = supplyQ.getQuantity(); + System.out.println(" Supplies Offered: [Quantity: " + supplyQuantity + ", Type: " +entityType.getEntityKind() + " "+ entityType.getDomain() + " "+ entityType.getCountry() + " "+ entityType.getCategory() + " "+ entityType.getSubCategory() + " "+ entityType.getSpecific() + " ]"); + + } + } + + //OTHER PDU TYPES + else { + System.out.println(receiptMessage); + } + } // end of bundle loop + + } // end of while loop + } // end try block // end try block // end try block // end try block + catch (IOException ioe) { + System.out.println(TRACE_PREFIX + "Problem with input/output, see exception trace:"); + System.out.println(ioe); + } + System.out.println(TRACE_PREFIX + "complete."); + } // end main +} // end class diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/test/WhiteSimulation.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/test/WhiteSimulation.java new file mode 100644 index 0000000000000000000000000000000000000000..ca5d0405f2a4e8a01709d9d8d89225fe8e991c8c --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/test/WhiteSimulation.java @@ -0,0 +1,483 @@ +/** + * Copyright (c) 2008-2020, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package MV3500Cohort2020JulySeptember.homework4.White.test; + +import MV3500Cohort2020JulySeptember.homework4.White.working.*; +import MV3500Cohort2020JulySeptember.homework4.White.*; +import edu.nps.moves.dis7.enumerations.*; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class WhiteSimulation +{ + // class variables + PduFactory pduFactory = new PduFactory(); + DisThreadedNetworkInterface disNetworkInterface; + DisThreadedNetworkInterface.PduListener pduListener; + Pdu receivedPdu; + + private String networkAddress = "10.1.105.7"; + private int networkPort = 3000; + + /** + * Constructor design goal: additional built-in initialization conveniences can go here + * to keep student efforts focused on the runSimulation() method. + */ + public WhiteSimulation() + { + // Under consideration. Constructor is not currently needed. + } + + /** + * Utility Constructor + * @param address network address to use + * @param port corresponding network port to use + */ + public WhiteSimulation(String address, int port) + { + setNetworkAddress(address); + + setNetworkPort(port); + } + + /** + * @return the networkAddress + */ + public String getNetworkAddress() + { + return networkAddress; + } + + /** + * @param networkAddress the networkAddress to set + */ + public final void setNetworkAddress(String networkAddress) + { + this.networkAddress = networkAddress; + } + + /** + * @return the networkPort + */ + public int getNetworkPort() + { + return networkPort; + } + + /** + * @param networkPort the networkPort to set + */ + public final void setNetworkPort(int networkPort) + { + this.networkPort = networkPort; + } + + /** + * Initialize network interface, choosing best available network interface + */ + public void setUpNetworkInterface() + { + disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); + + System.out.println("Network confirmation: address=" + disNetworkInterface.getMcastGroup() + " port=" + disNetworkInterface.getDisPort()); + pduListener = new DisThreadedNetworkInterface.PduListener() + { + /** Callback handler for listener */ + @Override + public void incomingPdu(Pdu newPdu) + { + receivedPdu = newPdu; + } + }; + disNetworkInterface.addListener(pduListener); + } + + /** All done, release network resources */ + public void tearDownNetworkInterface() + { + disNetworkInterface.removeListener(pduListener); + disNetworkInterface.kill(); + disNetworkInterface = null; + } + + /** + * Send a single Protocol Data Unit (PDU) of any type + * @param pdu the pdu to send + */ + private void sendSinglePdu(Pdu pdu) + { + try + { + disNetworkInterface.send(pdu); + Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally + } + catch (InterruptedException ex) + { + System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); + System.exit(1); + } + } + + /** + * Send EntityState, Fire, Comment PDUs + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + * @param entityStatePdu the ESPDU to send, if any + * @param firePdu the FirePDU to send, if any + * @param commentType enumeration value describing the narrative comment + * @param comments String array of narrative comments + */ + public void sendAllPdus(EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable length string + String... comments) + { + if (entityStatePdu != null) + sendPDU(entityStatePdu); + + if (firePdu != null) + sendPDU(firePdu); // bang + + if ((comments != null) && (comments.length > 0)) + { + ArrayList<String> newCommentsList = new ArrayList<>(); + for (int i = 0; i < comments.length; i++) + { + if (!comments[i].isEmpty()) + newCommentsList.add(comments[i]); // OK found something to send + } + if (!newCommentsList.isEmpty()) + { + if (commentType == null) + commentType = VariableRecordType.OTHER; + CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); + sendPDU(commentPdu); + } + } + } + + /** + * Main method is first executed when a program instance is loaded. + * @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a> + * @param args command-line arguments are an array of optional String parameters that are passed from execution environment during invocation + */ + public static void main(String[] args) + { + WhiteSimulation thisProgram = new WhiteSimulation(); // creates instance + + // initial execution: can handle args array of initialization arguments here + if (args.length == 2) + { + if ((args[0] != null) && !args[0].isEmpty()) + thisProgram.setNetworkAddress(args[0]); + + if ((args[1] != null) && !args[1].isEmpty()) + thisProgram.setNetworkPort(Integer.parseInt(args[1])); + } + else if (args.length != 0) + { + System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); + System.exit(-1); + } + // OK here we go... + + //thisProgram.setUpNetworkInterface(); + + thisProgram.runSimulation (); // customization code goes in there + + //thisProgram.tearDownNetworkInterface(); + } + + /** + * Programmer-modifiable method for defining and running a new simulation of interest. + * Support include DIS EntityStatePdu, FirePdu and CommentPdu all available for + * modification and sending in a simulation loop. + */ + @SuppressWarnings("SleepWhileInLoop") + public void runSimulation () + { + try + { + final double LOOP_DURATION_SECONDS = 1.0; // seconds + final int MAX_LOOP_COUNT = 10; + int loopCount = 0; + VariableRecordType narrativeType = VariableRecordType.OTHER; // of potential use + boolean simulationComplete = false; // sentinel variable as termination condition + boolean fireBool = false; + boolean destBool = false; + // TODO reset clock to zero each time for consistent outputs. + + // your model setup: who's who in this zoo? + // create PDU objects and set their values + + Vector3Double eloc3 = new Vector3Double(); + double[] loc3 = CoordinateConversions.getXYZfromLatLonDegrees(36.600757, -121.869309, 0 );//NPS Corner by lake + + EntityID entityID_1 = new EntityID(); + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID + + + + EntityStatePdu entityStatePdu = pduFactory.makeEntityStatePdu(); + entityStatePdu.setEntityID(entityID_1); + + // EntityMarking entityMarking = new EntityMarking (); + // entityMarking.setCharacters("WhiteSimulation".getBytes()); //entityMarking.setCharacters(Byte.valueOf("0")); // 11 characters max? + + // entityStatePdu.setMarking(entityMarking); + + + EntityID lavID = new EntityID(); + lavID.setSiteID(1); + lavID.setApplicationID(13); + lavID.setEntityID(25); + entityStatePdu.setEntityID(lavID); + EntityType lavType = new EntityType(); //1.1.225.2.41.3 Platform,Ground,USA,ArmoredFightingVehicle,LAV,LAV25A2 + lavType.setEntityKind(EntityKind.PLATFORM); + lavType.setDomain(Domain.inst(PlatformDomain.LAND)); + lavType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + lavType.setCategory(2); + lavType.setSubCategory(41); + lavType.setSpecific(3); + entityStatePdu.setEntityType(lavType); + + Vector3Double eloc2 = new Vector3Double(); + double[] loc2 = CoordinateConversions.getXYZfromLatLonDegrees(36.599831, -121.878842, 0); //sloat delmonte intersection + eloc2.setX(loc2[0]); + eloc2.setY(loc2[1]); + eloc2.setZ(loc2[2]); + entityStatePdu.setEntityLocation(eloc2); + EulerAngles orient2 = new EulerAngles(); + orient2.setPhi((float) 0.0); + orient2.setPsi((float) 0.0); + orient2.setTheta((float) 0.0); + entityStatePdu.setEntityOrientation(orient2); + + EntityStatePdu entityStatePdu2 = pduFactory.makeEntityStatePdu(); + + + EntityID bmpID = new EntityID(); + bmpID.setSiteID(1); + bmpID.setApplicationID(13); + bmpID.setEntityID(2); + entityStatePdu2.setEntityID(bmpID); + EntityType bmpType = new EntityType(); //1.1.222.2.2.1 Platform,Ground,Russia,ArmoredFightingVehicle,BMP2,BMP2 + bmpType.setEntityKind(EntityKind.PLATFORM); + bmpType.setDomain(Domain.inst(PlatformDomain.LAND)); + bmpType.setCountry(Country.RUSSIA); + bmpType.setCategory(2); + bmpType.setSubCategory(41); + bmpType.setSpecific(3); + entityStatePdu2.setEntityType(bmpType); + Vector3Double eloc1 = new Vector3Double(); + double[] loc1 = CoordinateConversions.getXYZfromLatLonDegrees(36.594116, -121.877463, 0); //NPS Main Gate + eloc1.setX(loc1[0]); + eloc1.setY(loc1[1]); + eloc1.setZ(loc1[2]); + + entityStatePdu2.setEntityLocation(eloc1); + EulerAngles orient1 = new EulerAngles(); + orient1.setPhi((float) 3.1415); + orient1.setPsi((float) 0.0); + orient1.setTheta((float) 0.0); + entityStatePdu2.setEntityOrientation(orient1); + + int BMPHitsReceived = 0; + + System.out.println(eloc2.toString()); + System.out.println(eloc1.toString()); + + //FirePdu firePduNull = new FirePdu(); + FirePdu firePdu = pduFactory.makeFirePdu(); + EntityID fireID = new EntityID(); + fireID.setSiteID(1); + fireID.setApplicationID(13); + fireID.setEntityID(25); + EntityID targetID = new EntityID(); + targetID.setSiteID(1); + targetID.setApplicationID(13); + targetID.setEntityID(2); + + firePdu.setFiringEntityID(fireID); + firePdu.setTargetEntityID(targetID); + + EntityType HEType = new EntityType(); //2.9.225.2.2.1 + HEType.setEntityKind(EntityKind.MUNITION); + HEType.setDomain(Domain.inst(PlatformDomain.AIR)); + HEType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + HEType.setCategory(2); + HEType.setSubCategory(2); + HEType.setSpecific(1); + MunitionDescriptor HEIT = new MunitionDescriptor(); + HEIT.setMunitionType(HEType); + HEIT.setQuantity(3); + HEIT.setFuse(MunitionDescriptorFuse.CONTACT_GRAZE); + HEIT.setRate(200); + + firePdu.setDescriptor(HEIT); + EntityID HEID = new EntityID(); + HEID.setEntityID(1); + firePdu.setMunitionExpendibleID(HEID); + + // + + + CommentReliablePdu bmpDestroyedComment = pduFactory.makeCommentReliablePdu("BMP2 DESTROYED BY LAV25-A2 AFTER TWO BURSTS OF 25mm HEI-T ON TARGET"); + CommentReliablePdu bmpSightedComment = pduFactory.makeCommentReliablePdu("LAV25-A2 ACQUIRES TARGET BMP2 WITHIN FIRING DISTANCE"); + //if(eloc1.getX()) + EntityID MTVRID = new EntityID(); + + ResupplyOfferPdu resupplyOfferPdu = pduFactory.makeResupplyOfferPdu(); + ArrayList<SupplyQuantity> pSupplies = new ArrayList<SupplyQuantity>(); + SupplyQuantity ammoSupplyQ = new SupplyQuantity(); + ammoSupplyQ.setSupplyType(HEType); + ammoSupplyQ.setQuantity(500); + + //EntityType ammoSupply = new EntityType(); + // ammoSupply.setEntityKind(EntityKind.MUNITION); + //ammoSupply.setDomain(Entity) + //ammoSupplyQ.setSupplyType(EntityType.) + pSupplies.add(ammoSupplyQ); + resupplyOfferPdu.setSupplies(pSupplies); + resupplyOfferPdu.setReceivingEntityID(lavID); + resupplyOfferPdu.setSupplyingEntityID(MTVRID); + + // should we customize this munition? what is it for your simulation? + + while (loopCount < MAX_LOOP_COUNT) // loop the simulation while allowed, can set additional conditions to break + { + String narrativeMessage1, narrativeMessage2, narrativeMessage3, narrativeMessage4; + narrativeMessage4 = ""; + // initialize loop variables + loopCount++; + + // ============================================================================================= + // your own simulation code starts here! + + // compute a track, update an ESPDU, whatever it is that your model is doing... + + // Where is my entity? + entityStatePdu.getEntityLocation().setX(entityStatePdu.getEntityLocation().getX() - 20); // 1m per timestep + entityStatePdu.getEntityLocation().setY(entityStatePdu.getEntityLocation().getY() - 75); + // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoort at! + Double dx = eloc2.getX() - eloc1.getX(); + Double dy = eloc2.getY() - eloc1.getY(); + Double dz = eloc2.getZ() - eloc1.getZ(); + Double range = Math.sqrt(dx*dx + dy*dy); + System.out.println("range" + range + " dx:" +dx + " dy:"+ dy); + // etc. etc. your code goes here + + if(range < 100){ + if (!fireBool) + sendPDU(bmpSightedComment); + fireBool = true; + System.out.println("Entity#" + firePdu.getFiringEntityID().getEntityID() + " is firing " + firePdu.getDescriptor().getMunitionType().getDomain() + "."+firePdu.getDescriptor().getMunitionType().getCountry() + "." + firePdu.getDescriptor().getMunitionType().getCategory() + "."+ firePdu.getDescriptor().getMunitionType().getSubCategory() + "." + firePdu.getDescriptor().getMunitionType().getSpecific() + "."+ " at Entity#"+ firePdu.getTargetEntityID().getEntityID()); + + + if(firePdu.getTargetEntityID().getEntityID() == 2){ + BMPHitsReceived += 1; + if (BMPHitsReceived > 1) { + //DESTROY THE BMP! + + System.out.println("BMP Destroyed after "+ BMPHitsReceived + " hits from 25mm HEI-T"); + narrativeMessage4 = "Destroyed BMP2"; + destBool = true; + + } + } + } + + + // your loop termination condition goes here + if (loopCount > 4) // for example + { + simulationComplete = true; + } + // your own simulation code is finished here! + // ============================================================================================= + + // keep track of timestep: wait duration for elapsed time in this loop + // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes + Thread.sleep((long)(LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds + System.out.println ("... Pausing for " + LOOP_DURATION_SECONDS + " seconds"); + + // send the status PDUs for this loop and continue + System.out.println ("sending PDUs for simulation step " + loopCount + ", monitor loopback to confirm sent"); + //sendAllPdus(entityStatePdu, firePduNull, null, narrativeMessage1, narrativeMessage2, narrativeMessage3); + //sendAllPdus(entityStatePdu2, null, null, narrativeMessage1, narrativeMessage2, narrativeMessage4); + sendPDU(entityStatePdu); + sendPDU(entityStatePdu2); + if (fireBool) + sendPDU(firePdu); + if (destBool){ + sendPDU(bmpDestroyedComment); + sendPDU(resupplyOfferPdu); + } + + System.out.println ("... PDUs successfully sent"); + + // =============================== + // loop now finished, thus terminate if simulation complete, otherwise send latest PDUs and continue + if (simulationComplete || (loopCount > 10000)) // for example; including fail-safe condition is good + { + CommentReliablePdu completionPdu = pduFactory.makeCommentReliablePdu("White Simulation Completed"); + sendPDU(completionPdu); + System.out.println ("... Termination condition met, simulationComplete=" + simulationComplete); + break; + } + } // end of while loop + } + catch (Exception ex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(WhiteSimulation.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public void sendPDU(Pdu pdu) { + System.out.println("Sending a PDU"); + MulticastSocket socket = null; // must be initialized, even if null + InetAddress destinationIp = null; // must be initialized, even if null + + try { + destinationIp = InetAddress.getByName(networkAddress); + } catch (UnknownHostException e) { + System.out.println(e + " Cannot create address"); + System.exit(0); + } + try { + // Set up a socket to send information + socket = new MulticastSocket(3000); + } catch (IOException ex) { + Logger.getLogger(WhiteSimulation.class.getName()).log(Level.SEVERE, null, ex); + } + + Set<InetAddress> broadcastAddresses; + // Loop through sending one ESPDUs + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + try { + pdu.marshal(dos); + byte[] data = baos.toByteArray(); + + DatagramPacket packet = new DatagramPacket(data, data.length, destinationIp, 3000); + socket.send(packet); + socket.close(); + } catch (Exception ex) { + Logger.getLogger(WhiteSimulation.class.getName()).log(Level.SEVERE, null, ex); + } +} +} \ No newline at end of file diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/PDUReciever.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/PDUReciever.java new file mode 100755 index 0000000000000000000000000000000000000000..2c57207923d4cfd8734ae0673de147f6b807ae91 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/PDUReciever.java @@ -0,0 +1,143 @@ +package MV3500Cohort2020JulySeptember.homework4.White.working; + +import java.io.*; +import java.net.*; +import java.util.*; + +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; + +/** + * Receives PDUs from GermanyEspduReceiverEspduVPNSender in IEEE DIS format. + * + * @date 09/05/2020 + * @author Bernd/Stefan + * @version 0.1 + */ +public class PDUReciever { + + /** + * Max size of a PDU in binary format that we can receive. This is actually + * somewhat outdated--PDUs can be larger--but this is a reasonable starting + * point. + */ + public static final int MAX_PDU_SIZE = 8192; + + /** + * Default port used, matches Wireshark DIS capture default + */ + public static final int DEFAULT_PORT = 3000; + public static final int SECOND_PORT = 3000; + public static final int THIRD_PORT = 2318; + + + /** + * Output prefix to identify this class + */ + private final static String TRACE_PREFIX = "[" + PDUReciever.class.getName() + "] "; + + public static void main(String args[]) { + System.out.println(TRACE_PREFIX + "started..."); + + MulticastSocket socket1; + MulticastSocket socket2; + MulticastSocket socket3; + DatagramPacket packet; + DatagramPacket packet2; + DatagramPacket packet3; + PduFactory pduFactory = new PduFactory(); + ArrayList<EntityID> knownEntities = new ArrayList<EntityID>(); + int pduCount = 0; + + try { + // Specify the socket to receive data + socket1 = new MulticastSocket(DEFAULT_PORT); + socket2 = new MulticastSocket(SECOND_PORT); + socket3 = new MulticastSocket(THIRD_PORT); + + System.out.println(TRACE_PREFIX + "listening for PDU packets on port " + DEFAULT_PORT );//+ " " + SECOND_PORT + " " + THIRD_PORT); + System.out.println("===================================================="); + + while (true) // Loop infinitely, receiving datagrams + { + byte buffer[] = new byte[MAX_PDU_SIZE]; + packet = new DatagramPacket(buffer, buffer.length); + + socket1.receive(packet); + + + + List<Pdu> pduBundle = pduFactory.getPdusFromBundle(packet.getData(), packet.getLength()); + if (pduBundle.size() > 1) { // should be 1 for this project + System.out.println("Bundle size is " + pduBundle.size()); + } + + // end iterator loop through PDU bundle + for (Pdu aPdu : pduBundle) { + pduCount++; + String receiptMessage = String.format("%3s", pduCount) // right justify, 3 characters + + ". received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName() + " from " + packet.getAddress(); + if (aPdu instanceof EntityStatePdu) { + System.out.println(receiptMessage); + EntityID entityID = ((EntityStatePdu) aPdu).getEntityID(); + Vector3Double position = ((EntityStatePdu) aPdu).getEntityLocation(); + System.out.println(" entityID triplet: [" + entityID.getSiteID() + ", " + entityID.getApplicationID() + ", " + entityID.getEntityID() + "] "); + if (!knownEntities.contains(entityID)){ + knownEntities.add(entityID); + EntityType entityType = ((EntityStatePdu) aPdu).getEntityType(); + System.out.println(" New Entity: " +entityType.getEntityKind() + " "+ entityType.getDomain() + " "+ entityType.getCountry() + " "+ entityType.getCategory() + " "+ entityType.getSubCategory() + " "+ entityType.getSpecific() ); + } + System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + + } + else if (aPdu instanceof FirePdu){ + System.out.println(receiptMessage); + EntityID firingEntityID = ((FirePdu) aPdu).getFiringEntityID(); + EntityID targetEntityID = ((FirePdu) aPdu).getTargetEntityID(); + MunitionDescriptor munitionDescriptor = ((FirePdu) aPdu).getDescriptor(); + System.out.println(" firingEntityID triplet: [" + firingEntityID.getSiteID() + ", " + firingEntityID.getApplicationID() + ", " + firingEntityID.getEntityID() + "] "); + System.out.println(" targetEntityID triplet: [" + targetEntityID.getSiteID() + ", " + targetEntityID.getApplicationID() + ", " + targetEntityID.getEntityID() + "] "); + System.out.println(" Munition Information: [" + munitionDescriptor.getMunitionType().getDomain() + "."+munitionDescriptor.getMunitionType().getCountry() + "." + munitionDescriptor.getMunitionType().getCategory() + "."+ munitionDescriptor.getMunitionType().getSubCategory() + "." + munitionDescriptor.getMunitionType().getSpecific() + "]"); + } + else if (aPdu instanceof CommentReliablePdu){ + System.out.println(receiptMessage); + ArrayList<VariableDatum> payloadList = (ArrayList)((CommentReliablePdu) aPdu).getVariableDatumRecords(); + if (!payloadList.isEmpty()) + System.out.print (" messages: "); + for (VariableDatum variableDatum : payloadList) + { + String nextComment = new String(variableDatum.getVariableDatumValue()); // convert byte[] to String + System.out.print (" \"" + nextComment + "\""); + System.out.println(); + }// + } + else if (aPdu instanceof ResupplyOfferPdu){ + System.out.println(receiptMessage); + EntityID receiverID = ((ResupplyOfferPdu) aPdu).getReceivingEntityID(); + EntityID supplierID = ((ResupplyOfferPdu) aPdu).getSupplyingEntityID(); + List<SupplyQuantity> supplyList = ((ResupplyOfferPdu) aPdu).getSupplies(); + System.out.println(" Resupply Offer from Entity [" + supplierID.getSiteID() + ", "+ supplierID.getApplicationID() + ", " + supplierID.getEntityID() + "] to resupply Entity ["+ receiverID.getSiteID() + ", "+ receiverID.getApplicationID() + ", " + receiverID.getEntityID() + "]" ); + for (int i = 0; i < supplyList.size(); i++){ + SupplyQuantity supplyQ = supplyList.get(i); + EntityType entityType = supplyQ.getSupplyType(); + float supplyQuantity = supplyQ.getQuantity(); + System.out.println(" Supplies Offered: [Quantity: " + supplyQuantity + ", Type: " +entityType.getEntityKind() + " "+ entityType.getDomain() + " "+ entityType.getCountry() + " "+ entityType.getCategory() + " "+ entityType.getSubCategory() + " "+ entityType.getSpecific() + " ]"); + + } + } + + //OTHER PDU TYPES + else { + System.out.println(receiptMessage); + } + } // end of bundle loop + + } // end of while loop + } // end try block // end try block // end try block // end try block + catch (IOException ioe) { + System.out.println(TRACE_PREFIX + "Problem with input/output, see exception trace:"); + System.out.println(ioe); + } + System.out.println(TRACE_PREFIX + "complete."); + } // end main +} // end class diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/PduListenerSaver.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/PduListenerSaver.java new file mode 100644 index 0000000000000000000000000000000000000000..e5149fdb471eb39a06a4db3475df5acdffba9787 --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/PduListenerSaver.java @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2008-2020, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package MV3500Cohort2020JulySeptember.homework4.White.working; + +import edu.nps.moves.dis7.utilities.stream.PduRecorder; +import java.io.IOException; +import java.util.Scanner; + +/** Class to leverage the {@link edu.nps.moves.dis7.utilities.stream.PduRecorder} + * with PDU log saving console controls for resume, pause and quit. + * + * PduSaver.java created on Aug 21, 2019 + * Renamed PduListenerSaver + * MOVES Institute Naval Postgraduate School, Monterey, CA, USA www.nps.edu + * + * @author Mike Bailey, jmbailey@nps.edu + * @version $Id$ + */ +public class PduListenerSaver +{ + private final static String DEFAULT_OUTPUT_DIRECTORY = "pduLog"; + public static final String DEFAULT_MULTICAST_ADDRESS = "localhost"; + public static final int DEFAULT_MULTICAST_PORT = 2137; + + private enum mystate + { + RUNNING, + PAUSED; + } + + public static void main(String[] args) + { + String outputDirectory = DEFAULT_OUTPUT_DIRECTORY; + String multicastAddress = DEFAULT_MULTICAST_ADDRESS; + int multicastPort = DEFAULT_MULTICAST_PORT; + + System.out.println("OpenDis7Examples.PduListenerSaver started..."); + + switch (args.length) { + case 0: + break; + case 1: + outputDirectory = args[0]; + break; + case 3: + outputDirectory = args[0]; + multicastAddress = args[1]; + multicastPort = Integer.parseInt(args[2]); + break; + default: + // Common-sense practice is to print help message if invocation is problematic + System.err.println("Usage: PduListenerSaver() or PduListenerSaver(\"outputdir\") or PduListenerSaver(\"outputDirectory\",\"multicastAddress\", multicastPort"); + System.exit(1); + } + + System.out.println("Beginning PduListenerSaver (" + multicastAddress + ":" + multicastPort + ") to directory " + outputDirectory); + try { + PduRecorder recorder = new PduRecorder(outputDirectory, multicastAddress, multicastPort); // assumes save + mystate state = mystate.RUNNING; + Scanner scan = new Scanner(System.in); + + while (true) { + System.out.println("Type p/enter to pause, r/enter to resume, q/enter to quit"); + String line = scan.nextLine(); + if (line.equalsIgnoreCase("p") && state == mystate.RUNNING) { + recorder.stopPause(); + state = mystate.PAUSED; + System.out.println("... now PAUSED"); + } + else if (line.equalsIgnoreCase("p")) { + System.out.println("... still PAUSED"); + } + else if (line.equalsIgnoreCase("r") && state == mystate.PAUSED) { + recorder.startResume(); + state = mystate.RUNNING; + System.out.println("... now RUNNING"); + } + else if (line.equalsIgnoreCase("r")) { + System.out.println("... still RUNNING"); + } + else if (line.equalsIgnoreCase("q")) { + System.out.println("... QUIT"); + recorder.end(); + break; + } + } + System.out.println("Ending PduListenerSaver pdu recording, saved to file:"); + System.out.println(recorder.getLogFilePath()); + } + catch (IOException ex) { + System.err.println("Exception: " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage()); + } + } +} diff --git a/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/WhiteSimulation.java b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/WhiteSimulation.java new file mode 100644 index 0000000000000000000000000000000000000000..ebee25ed486ab4686f7ab3bc88430a30e5fea01e --- /dev/null +++ b/assignments/src/MV3500Cohort2020JulySeptember/homework4/White/working/WhiteSimulation.java @@ -0,0 +1,473 @@ +/** + * Copyright (c) 2008-2020, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package MV3500Cohort2020JulySeptember.homework4.White.working; + +import MV3500Cohort2020JulySeptember.homework4.White.*; +import edu.nps.moves.dis7.enumerations.*; +import edu.nps.moves.dis7.pdus.*; +import edu.nps.moves.dis7.utilities.*; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class WhiteSimulation +{ + // class variables + PduFactory pduFactory = new PduFactory(); + DisThreadedNetworkInterface disNetworkInterface; + DisThreadedNetworkInterface.PduListener pduListener; + Pdu receivedPdu; + + private String networkAddress = "10.1.105.7"; + private int networkPort = 2317; + + /** + * Constructor design goal: additional built-in initialization conveniences can go here + * to keep student efforts focused on the runSimulation() method. + */ + public WhiteSimulation() + { + // Under consideration. Constructor is not currently needed. + } + + /** + * Utility Constructor + * @param address network address to use + * @param port corresponding network port to use + */ + public WhiteSimulation(String address, int port) + { + setNetworkAddress(address); + + setNetworkPort(port); + } + + /** + * @return the networkAddress + */ + public String getNetworkAddress() + { + return networkAddress; + } + + /** + * @param networkAddress the networkAddress to set + */ + public final void setNetworkAddress(String networkAddress) + { + this.networkAddress = networkAddress; + } + + /** + * @return the networkPort + */ + public int getNetworkPort() + { + return networkPort; + } + + /** + * @param networkPort the networkPort to set + */ + public final void setNetworkPort(int networkPort) + { + this.networkPort = networkPort; + } + + /** + * Initialize network interface, choosing best available network interface + */ + public void setUpNetworkInterface() + { + disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); + + System.out.println("Network confirmation: address=" + disNetworkInterface.getMcastGroup() + " port=" + disNetworkInterface.getDisPort()); + pduListener = new DisThreadedNetworkInterface.PduListener() + { + /** Callback handler for listener */ + @Override + public void incomingPdu(Pdu newPdu) + { + receivedPdu = newPdu; + } + }; + disNetworkInterface.addListener(pduListener); + } + + /** All done, release network resources */ + public void tearDownNetworkInterface() + { + disNetworkInterface.removeListener(pduListener); + disNetworkInterface.kill(); + disNetworkInterface = null; + } + + /** + * Send a single Protocol Data Unit (PDU) of any type + * @param pdu the pdu to send + */ + private void sendSinglePdu(Pdu pdu) + { + try + { + disNetworkInterface.send(pdu); + Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally + } + catch (InterruptedException ex) + { + System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); + System.exit(1); + } + } + + /** + * Send EntityState, Fire, Comment PDUs + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + * @param entityStatePdu the ESPDU to send, if any + * @param firePdu the FirePDU to send, if any + * @param commentType enumeration value describing the narrative comment + * @param comments String array of narrative comments + */ + public void sendAllPdus(EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable length string + String... comments) + { + if (entityStatePdu != null) + sendPDU(entityStatePdu); + + if (firePdu != null) + sendPDU(firePdu); // bang + + if ((comments != null) && (comments.length > 0)) + { + ArrayList<String> newCommentsList = new ArrayList<>(); + for (int i = 0; i < comments.length; i++) + { + if (!comments[i].isEmpty()) + newCommentsList.add(comments[i]); // OK found something to send + } + if (!newCommentsList.isEmpty()) + { + if (commentType == null) + commentType = VariableRecordType.OTHER; + CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); + sendPDU(commentPdu); + } + } + } + + /** + * Main method is first executed when a program instance is loaded. + * @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a> + * @param args command-line arguments are an array of optional String parameters that are passed from execution environment during invocation + */ + public static void main(String[] args) + { + WhiteSimulation thisProgram = new WhiteSimulation(); // creates instance + + // initial execution: can handle args array of initialization arguments here + if (args.length == 2) + { + if ((args[0] != null) && !args[0].isEmpty()) + thisProgram.setNetworkAddress(args[0]); + + if ((args[1] != null) && !args[1].isEmpty()) + thisProgram.setNetworkPort(Integer.parseInt(args[1])); + } + else if (args.length != 0) + { + System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); + System.exit(-1); + } + // OK here we go... + + //thisProgram.setUpNetworkInterface(); + + thisProgram.runSimulation (); // customization code goes in there + + //thisProgram.tearDownNetworkInterface(); + } + + /** + * Programmer-modifiable method for defining and running a new simulation of interest. + * Support include DIS EntityStatePdu, FirePdu and CommentPdu all available for + * modification and sending in a simulation loop. + */ + @SuppressWarnings("SleepWhileInLoop") + public void runSimulation () + { + try + { + final double LOOP_DURATION_SECONDS = 1.0; // seconds + final int MAX_LOOP_COUNT = 10; + int loopCount = 0; + VariableRecordType narrativeType = VariableRecordType.OTHER; // of potential use + boolean simulationComplete = false; // sentinel variable as termination condition + boolean fireBool = false; + boolean destBool = false; + // TODO reset clock to zero each time for consistent outputs. + + // your model setup: who's who in this zoo? + // create PDU objects and set their values + + Vector3Double eloc3 = new Vector3Double(); + double[] loc3 = CoordinateConversions.getXYZfromLatLonDegrees(36.600757, -121.869309, 0 );//NPS Corner by lake + + EntityID entityID_1 = new EntityID(); + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID + + + + EntityStatePdu entityStatePdu = pduFactory.makeEntityStatePdu(); + entityStatePdu.setEntityID(entityID_1); + + + + EntityID lavID = new EntityID(); + lavID.setSiteID(1); + lavID.setApplicationID(13); + lavID.setEntityID(25); + + entityStatePdu.setEntityID(lavID); + EntityType lavType = new EntityType(); //1.1.225.2.41.3 Platform,Ground,USA,ArmoredFightingVehicle,LAV,LAV25A2 + lavType.setEntityKind(EntityKind.PLATFORM); + lavType.setDomain(Domain.inst(PlatformDomain.LAND)); + lavType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + lavType.setCategory(2); + lavType.setSubCategory(41); + lavType.setSpecific(3); + entityStatePdu.setEntityType(lavType); + + Vector3Double eloc2 = new Vector3Double(); + double[] loc2 = CoordinateConversions.getXYZfromLatLonDegrees(36.599831, -121.878842, 0); //sloat delmonte intersection + eloc2.setX(loc2[0]); + eloc2.setY(loc2[1]); + eloc2.setZ(loc2[2]); + entityStatePdu.setEntityLocation(eloc2); + + EulerAngles orient2 = new EulerAngles(); + orient2.setPhi((float) 0.0); + orient2.setPsi((float) 0.0); + orient2.setTheta((float) 0.0); + entityStatePdu.setEntityOrientation(orient2); + + EntityStatePdu entityStatePdu2 = pduFactory.makeEntityStatePdu(); + + + EntityID bmpID = new EntityID(); + bmpID.setSiteID(1); + bmpID.setApplicationID(13); + bmpID.setEntityID(2); + entityStatePdu2.setEntityID(bmpID); + EntityType bmpType = new EntityType(); //1.1.222.2.2.1 Platform,Ground,Russia,ArmoredFightingVehicle,BMP2,BMP2 + bmpType.setEntityKind(EntityKind.PLATFORM); + bmpType.setDomain(Domain.inst(PlatformDomain.LAND)); + bmpType.setCountry(Country.RUSSIA); + bmpType.setCategory(2); + bmpType.setSubCategory(41); + bmpType.setSpecific(3); + entityStatePdu2.setEntityType(bmpType); + Vector3Double eloc1 = new Vector3Double(); + double[] loc1 = CoordinateConversions.getXYZfromLatLonDegrees(36.594116, -121.877463, 0); //NPS Main Gate + eloc1.setX(loc1[0]); + eloc1.setY(loc1[1]); + eloc1.setZ(loc1[2]); + + entityStatePdu2.setEntityLocation(eloc1); + EulerAngles orient1 = new EulerAngles(); + orient1.setPhi((float) 3.1415); + orient1.setPsi((float) 0.0); + orient1.setTheta((float) 0.0); + entityStatePdu2.setEntityOrientation(orient1); + + int BMPHitsReceived = 0; + + System.out.println(eloc2.toString()); + System.out.println(eloc1.toString()); + + //FirePdu firePduNull = new FirePdu(); + FirePdu firePdu = pduFactory.makeFirePdu(); + EntityID fireID = new EntityID(); + fireID.setSiteID(1); + fireID.setApplicationID(13); + fireID.setEntityID(25); + + EntityID targetID = new EntityID(); + targetID.setSiteID(1); + targetID.setApplicationID(13); + targetID.setEntityID(2); + + firePdu.setFiringEntityID(fireID); + firePdu.setTargetEntityID(targetID); + + EntityType HEType = new EntityType(); //2.9.225.2.2.1 MUNITION AIR USA BALLISTIC 25MM HEI-T + HEType.setEntityKind(EntityKind.MUNITION); + HEType.setDomain(Domain.inst(PlatformDomain.AIR)); + HEType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); + HEType.setCategory(2); + HEType.setSubCategory(2); + HEType.setSpecific(1); + + MunitionDescriptor HEIT = new MunitionDescriptor(); + HEIT.setMunitionType(HEType); + HEIT.setQuantity(3); + HEIT.setFuse(MunitionDescriptorFuse.CONTACT_GRAZE); + HEIT.setRate(200); + + firePdu.setDescriptor(HEIT); + EntityID HEID = new EntityID(); + HEID.setEntityID(1); + firePdu.setMunitionExpendibleID(HEID); + + // + + + CommentReliablePdu bmpDestroyedComment = pduFactory.makeCommentReliablePdu("BMP2 DESTROYED BY LAV25-A2 AFTER TWO BURSTS OF 25mm HEI-T ON TARGET"); + CommentReliablePdu bmpSightedComment = pduFactory.makeCommentReliablePdu("LAV25-A2 ACQUIRES TARGET BMP2 WITHIN FIRING DISTANCE"); + //if(eloc1.getX()) + + + + // should we customize this munition? what is it for your simulation? + + while (loopCount < MAX_LOOP_COUNT) // loop the simulation while allowed, can set additional conditions to break + { + String narrativeMessage1, narrativeMessage2, narrativeMessage3, narrativeMessage4; + narrativeMessage4 = ""; + // initialize loop variables + loopCount++; + + // ============================================================================================= + // your own simulation code starts here! + + // compute a track, update an ESPDU, whatever it is that your model is doing... + + // Where is my entity? + entityStatePdu.getEntityLocation().setX(entityStatePdu.getEntityLocation().getX() - 20); // 1m per timestep + entityStatePdu.getEntityLocation().setY(entityStatePdu.getEntityLocation().getY() - 75); + + Double dx = eloc2.getX() - eloc1.getX(); + Double dy = eloc2.getY() - eloc1.getY(); + Double dz = eloc2.getZ() - eloc1.getZ(); + Double range = Math.sqrt(dx*dx + dy*dy); + System.out.println("range" + range + " dx:" +dx + " dy:"+ dy); + + if(range < 100){ + if (!fireBool) + sendPDU(bmpSightedComment); + fireBool = true; + System.out.println("Entity#" + firePdu.getFiringEntityID().getEntityID() + " is firing " + firePdu.getDescriptor().getMunitionType().getDomain() + "."+firePdu.getDescriptor().getMunitionType().getCountry() + "." + firePdu.getDescriptor().getMunitionType().getCategory() + "."+ firePdu.getDescriptor().getMunitionType().getSubCategory() + "." + firePdu.getDescriptor().getMunitionType().getSpecific() + "."+ " at Entity#"+ firePdu.getTargetEntityID().getEntityID()); + + if(firePdu.getTargetEntityID().getEntityID() == 2){ + BMPHitsReceived += 1; + if (BMPHitsReceived > 1) { + //DESTROY THE BMP! + + System.out.println("BMP Destroyed after "+ BMPHitsReceived + " hits from 25mm HEI-T"); + narrativeMessage4 = "Destroyed BMP2"; + destBool = true; + + } + } + } + + + // your loop termination condition goes here + if (loopCount > 4) // for example + { + simulationComplete = true; + } + // your own simulation code is finished here! + // ============================================================================================= + + // keep track of timestep: wait duration for elapsed time in this loop + // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes + Thread.sleep((long)(LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds + System.out.println ("... Pausing for " + LOOP_DURATION_SECONDS + " seconds"); + + // send the status PDUs for this loop and continue + System.out.println ("sending PDUs for simulation step " + loopCount + ", monitor loopback to confirm sent"); + //sendAllPdus(entityStatePdu, firePduNull, null, narrativeMessage1, narrativeMessage2, narrativeMessage3); + //sendAllPdus(entityStatePdu2, null, null, narrativeMessage1, narrativeMessage2, narrativeMessage4); + sendPDU(entityStatePdu); + sendPDU(entityStatePdu2); + if (fireBool) + sendPDU(firePdu); + if (destBool){ + sendPDU(bmpDestroyedComment); + } + + System.out.println ("... PDUs successfully sent"); + + // =============================== + // loop now finished, thus terminate if simulation complete, otherwise send latest PDUs and continue + if (simulationComplete || (loopCount > 10000)) // for example; including fail-safe condition is good + { + CommentReliablePdu completionPdu = pduFactory.makeCommentReliablePdu("White Simulation Completed"); + sendPDU(completionPdu); + System.out.println ("... Termination condition met, simulationComplete=" + simulationComplete); + break; + } + } // end of while loop + } + catch (Exception ex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(WhiteSimulation.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public void sendPDU(Pdu pdu) { + System.out.println("Sending a PDU"); + MulticastSocket socket = null; // must be initialized, even if null + InetAddress destinationIp = null; // must be initialized, even if null + + try { + destinationIp = InetAddress.getByName(networkAddress); + } catch (UnknownHostException e) { + System.out.println(e + " Cannot create address"); + System.exit(0); + } + try { + // Set up a socket to send information + socket = new MulticastSocket(2317); + } catch (IOException ex) { + Logger.getLogger(WhiteSimulation.class.getName()).log(Level.SEVERE, null, ex); + } + + Set<InetAddress> broadcastAddresses; + // Loop through sending one ESPDUs + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + DatagramPacket packet = new DatagramPacket(baos.toByteArray(), baos.size(), destinationIp, 2317);//trying new things + try { + pdu.marshal(dos); + //byte[] data = baos.toByteArray(); + + //DatagramPacket packet = new DatagramPacket(data, data.length, destinationIp, 2317); + packet.setData(baos.toByteArray());// + + + socket.send(packet); + + dos.flush(); // immediately force pdu write + baos.reset();// + + socket.close(); + } catch (Exception ex) { + Logger.getLogger(WhiteSimulation.class.getName()).log(Level.SEVERE, null, ex); + } +} +} \ No newline at end of file diff --git a/build.xml b/build.xml index b48845a177f86db43b55a53aa1384f4e273d42d9..d794938d6c2791d0d8189ee423e9aa303f019220 100644 --- a/build.xml +++ b/build.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 1995-2019 held by the author(s). All rights reserved. + Copyright (c) 1995-2020 held by the author(s). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -39,7 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. Author : Don Brutzman and Don McGregor Description: Ant build.xml file for Networked Graphics MV3500 --> -<project name="Networked_Graphics_MV3500" default="all" basedir="."> +<project name="MV3500 Networked Graphics" default="all" basedir="."> <description>Build targets for NPS Networked Graphics MV3500</description> <!-- TODO add targets for project maintenance, testing and deployment @@ -84,22 +84,48 @@ POSSIBILITY OF SUCH DAMAGE. <nbbrowse url="https://github.com/open-dis"/> </target> - <target name="update.open-dis7.jar.local" description="update open-dis7.jar in project lib directory"> - <!-- TODO get clearer about what each of 4 jar files might be --> - <property name="open-dis7-java.relative" value="../open-dis7-java/dist"/> - <echo message="copy ${open-dis7-java.relative}/open-dis7-java.jar to project lib/ subdirectory"/> + <target name="update.open-dis7.jar.local" description="update open-dis7-java jar files from locally built project into lib directory"> + + <property name="open-dis7-java.relative" value="../../x3d-github/open-dis7-java/dist"/> + <echo message="copy ${open-dis7-java.relative}/open-dis7-java.jar and related jar files to project lib/ subdirectory"/> <!-- https://ant.apache.org/manual/Tasks/fail.html --> - <fail message="open-dis7-java.jar not found"> + <fail message="open-dis7-enumerations-classes.jar not found"> <condition> <not> <resourcecount count="1"> - <fileset id="fs" dir="${open-dis7-java.relative}" includes="open-dis7-java.jar"/><!-- comma separated --> + <fileset id="fs" dir="${open-dis7-java.relative}" includes="open-dis7-enumerations-classes.jar"/><!-- comma separated --> </resourcecount> </not> </condition> </fail> - <delete file="lib/open-dis7-java.jar" verbose="true" /> - <copy file="${open-dis7-java.relative}/open-dis7-java.jar" todir="lib" force="true" verbose="true" failonerror="true"/> + <delete file="lib/open-dis7-enumerations-classes.jar" verbose="true" failonerror="false"/> + <delete file="lib/open-dis7-enumerations-javadoc.jar" verbose="true" failonerror="false"/> + <delete file="lib/open-dis7-enumerations-source.jar" verbose="true" failonerror="false"/> + + <copy file="${open-dis7-java.relative}/open-dis7-enumerations-classes.jar" todir="lib" force="true" verbose="true" failonerror="true"/> + <copy file="${open-dis7-java.relative}/open-dis7-enumerations-source.jar" todir="lib" force="true" verbose="true" failonerror="true"/> + <copy file="${open-dis7-java.relative}/open-dis7-enumerations-javadoc.jar" todir="lib" force="true" verbose="true" failonerror="true"/> + + <fail message="open-dis7-pdus-classes.jar not found"> + <condition> + <not> + <resourcecount count="1"> + <fileset id="fs" dir="${open-dis7-java.relative}" includes="open-dis7-pdus-classes.jar"/><!-- comma separated --> + </resourcecount> + </not> + </condition> + </fail> + <delete file="lib/open-dis7-classes.jar" verbose="true" failonerror="false"/><!-- prior name --> + <delete file="lib/open-dis7-javadoc.jar" verbose="true" failonerror="false"/><!-- prior name --> + <delete file="lib/open-dis7-source.jar" verbose="true" failonerror="false"/><!-- prior name --> + + <delete file="lib/open-dis7-pdus-classes.jar" verbose="true" failonerror="false"/> + <delete file="lib/open-dis7-pdus-javadoc.jar" verbose="true" failonerror="false"/> + <delete file="lib/open-dis7-pdus-source.jar" verbose="true" failonerror="false"/> + + <copy file="${open-dis7-java.relative}/open-dis7-pdus-classes.jar" todir="lib" force="true" verbose="true" failonerror="true"/> + <copy file="${open-dis7-java.relative}/open-dis7-pdus-javadoc.jar" todir="lib" force="true" verbose="true" failonerror="true"/> + <copy file="${open-dis7-java.relative}/open-dis7-pdus-source.jar" todir="lib" force="true" verbose="true" failonerror="true"/> </target> <target name="update.open-dis7.jar.gitlab" description="update open-dis7.jar in project lib directory"> diff --git a/conferences/IITSEC2020/IITSEC2020_DIS_Tutorial_20031.pdf b/conferences/IITSEC2020/IITSEC2020_DIS_Tutorial_20031.pdf index c42923a6374716625931eeeaaa9a50b1272e0e8b..099548f8fbe25243c0818c9f302a4c3249983ae6 100644 Binary files a/conferences/IITSEC2020/IITSEC2020_DIS_Tutorial_20031.pdf and b/conferences/IITSEC2020/IITSEC2020_DIS_Tutorial_20031.pdf differ diff --git a/conferences/IITSEC2020/IITSEC2020_DIS_Tutorial_20031.pptx b/conferences/IITSEC2020/IITSEC2020_DIS_Tutorial_20031.pptx index c6bc50c3edec43270d6dfd1bf22073ec01831d65..7a71a9293078661163f9b2356334622ba81c6533 100644 Binary files a/conferences/IITSEC2020/IITSEC2020_DIS_Tutorial_20031.pptx and b/conferences/IITSEC2020/IITSEC2020_DIS_Tutorial_20031.pptx differ diff --git a/documentation/Wireshark/README.md b/documentation/Wireshark/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4ce32c0fd9eac8b80598ef60934534c18bcbe23c --- /dev/null +++ b/documentation/Wireshark/README.md @@ -0,0 +1,63 @@ +# Wireshark Setup and Usage <a href="https://www.wireshark.org"><img src="images/wireshark_logo.png" align="right"/></a> + +> Wireshark is the world’s foremost and widely-used network protocol analyzer. +> It lets you see what’s happening on your network at a microscopic level and +> is the de facto (and often de jure) standard across many commercial and non-profit enterprises, +> government agencies, and educational institutions. +> Wireshark development thrives thanks to the volunteer contributions of networking experts +> around the globe and is the continuation of a project started by Gerald Combs in 1998. + +[Wireshark](https://www.wireshark.org) is an excellent open-source tool with wide use. +Capabilities include inspection of <code>dis</code> packets. + +[Capturing DIS Packets](Capturing_DIS_Packets.pdf) by Tobias Brennenstuhl is his +[thesis annex](https://calhoun.nps.edu/handle/10945/65436) +specifically written to help support student efforts. + +## Installation and Configuration + +IMPORTANT: if you have already installed Wireshark, check your version! +Always use the latest so that operating-system security and feature sets are up to date. + +1. Download Wireshark from https://www.wireshark.org +2. Install as local administrator if possible +3. Launch and see if network packets are being detected. + +| Successful installation, monitoring | Failed installation, no monitoring | +| ------ | ------ | +| <a href="images/WiresharkNetworkInterfaces.png"><img src="images/WiresharkNetworkInterfaces.png" width="400" align="center"/></a> | <a href="images/WiresharkNoNetworkTraffic.png"><img src="images/WiresharkNoNetworkTraffic.png" width="400" align="center"/></a> | + +4. Check your network interfaces via console commands [ipconfig](ipconfig.txt) +5. Double-check network interfaces using [ipconfig /all](ipconfigAllExcerpt.txt) to see any hidden interfaces + +## Capturing Packets + +1. Confirm preferences: File > Preferences > Capture as shown + +<a href="images/WiresharkCapturePreferences.png"><img src="images/WiresharkCapturePreferences.png" width="400" align="center"/> + +2. Set filter to dis +3. Lauch one of the example programs to send packets, then observe results. + +<a href="images/WiresharkUdpDisPduCapture.png"><img src="images/WiresharkUdpDisPduCapture.png" width="400" align="center"/> + +## Troubleshooting + +1. Check your [firewall settings](Firewall_Configuration.pdf). (Again thanks to Tobias for another helpful reference.) +2. Compare Wireshark results with/without your [Virtual Private Network (VPN)](https://en.wikipedia.org/wiki/Virtual_private_network) active. +3. Compare Wireshark results when logged in as local administrator, if possible. +4. [StackOverflow](https://stackoverflow.com/search?q=wireshark) is an excellent resource for detailed technical questions, looking up error messages, etc. + +## Videos + +1. [Intro to Wireshark: Basics + Packet Analysis!](https://www.youtube.com/watch?v=TkCSr30UojM) by SinnohStarly - Ross Teixeira. +2. [Wireshark Tutorial for Beginners](https://www.youtube.com/watch?v=TkCSr30UojM) by Anson Alexander +3. [Back to Basics](https://www.youtube.com/watch?v=y13zH-8OPE8&t=9s) video by Hansang Bae. "Read.... READ I SAY!!!!" + +## References + +1. [Wireshark home page](https://www.wireshark.org) and [Learning Wireshark](https://www.wireshark.org/#learnWS) +2. [Wireshark User’s Guide](https://www.wireshark.org/docs/wsug_html_chunked) +3. [Wireshark Frequently Asked Questions (FAQ)](https://www.wireshark.org/faq.html) and [Ask Wireshark](https://ask.wireshark.org/questions) +4. [NPS Remote Access and Wireless Services](https://nps.edu/web/technology/remote-access) +5. Tobias Brennenstuhl, [REPEATABLE UNIT TESTING OF DISTRIBUTED INTERACTIVE SIMULATION (DIS) PROTOCOL BEHAVIOR STREAMS USING WEB STANDARDS](https://calhoun.nps.edu/handle/10945/65436), MOVES Masters Thesis, Naval Postgraduate School (NPS), Monterey California USA, June 2020. diff --git a/documentation/Wireshark/images/WiresharkCapturePreferences.png b/documentation/Wireshark/images/WiresharkCapturePreferences.png new file mode 100644 index 0000000000000000000000000000000000000000..9258ed18c6d7385b3418bd88195aeebe88d5be64 Binary files /dev/null and b/documentation/Wireshark/images/WiresharkCapturePreferences.png differ diff --git a/documentation/Wireshark/images/WiresharkNetworkInterfaces.png b/documentation/Wireshark/images/WiresharkNetworkInterfaces.png new file mode 100644 index 0000000000000000000000000000000000000000..61a3667521725777ab4185dd5e1dbf0af08dd0de Binary files /dev/null and b/documentation/Wireshark/images/WiresharkNetworkInterfaces.png differ diff --git a/documentation/Wireshark/images/WiresharkNoNetworkTraffic.png b/documentation/Wireshark/images/WiresharkNoNetworkTraffic.png new file mode 100644 index 0000000000000000000000000000000000000000..8ab66283adbb30d793d1104f79286e1f5c37ccf5 Binary files /dev/null and b/documentation/Wireshark/images/WiresharkNoNetworkTraffic.png differ diff --git a/documentation/Wireshark/images/WiresharkUdpDisPduCapture.png b/documentation/Wireshark/images/WiresharkUdpDisPduCapture.png new file mode 100644 index 0000000000000000000000000000000000000000..848707358b6dca6d7d14088670e94aa32655af2d Binary files /dev/null and b/documentation/Wireshark/images/WiresharkUdpDisPduCapture.png differ diff --git a/documentation/Wireshark/images/wireshark_logo.png b/documentation/Wireshark/images/wireshark_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b9df5762f595d77a5613b945e3cfdeade5782d70 Binary files /dev/null and b/documentation/Wireshark/images/wireshark_logo.png differ diff --git a/documentation/Wireshark/ipconfig.txt b/documentation/Wireshark/ipconfig.txt new file mode 100644 index 0000000000000000000000000000000000000000..29a00b1a839afb993a983dcda6aed39411aa9353 --- /dev/null +++ b/documentation/Wireshark/ipconfig.txt @@ -0,0 +1,33 @@ +Example "ipconfig" output: + +Windows IP Configuration + +Ethernet adapter Ethernet 7: + + Connection-specific DNS Suffix . : + IPv4 Address. . . . . . . . . . . : 172.20.223.70 + Subnet Mask . . . . . . . . . . . : 255.255.255.255 + Default Gateway . . . . . . . . . : 0.0.0.0 + +Ethernet adapter Ethernet: + + Media State . . . . . . . . . . . : Media disconnected + Connection-specific DNS Suffix . : ern.nps.edu + +Wireless LAN adapter Local Area Connection* 4: + + Media State . . . . . . . . . . . : Media disconnected + Connection-specific DNS Suffix . : + +Wireless LAN adapter Wi-Fi: + + Connection-specific DNS Suffix . : + Link-local IPv6 Address . . . . . : fe80::6c31:f4d3:2fc3:8b37%17 + IPv4 Address. . . . . . . . . . . : 10.0.0.9 + Subnet Mask . . . . . . . . . . . : 255.255.255.0 + Default Gateway . . . . . . . . . : 10.0.0.1 + +Ethernet adapter Bluetooth Network Connection: + + Media State . . . . . . . . . . . : Media disconnected + Connection-specific DNS Suffix . : diff --git a/documentation/Wireshark/ipconfigAllExcerpt.txt b/documentation/Wireshark/ipconfigAllExcerpt.txt new file mode 100644 index 0000000000000000000000000000000000000000..d1857033741d1ee64af49fc382017ecb66c55bea --- /dev/null +++ b/documentation/Wireshark/ipconfigAllExcerpt.txt @@ -0,0 +1,16 @@ +Here is "ipconfig /all" excerpt, which did not appear before: + +Ethernet adapter Ethernet 7: + Connection-specific DNS Suffix . : + Description . . . . . . . . . . . : PANGP Virtual Ethernet Adapter #5 + Physical Address. . . . . . . . . : 02-50-41-00-00-01 + DHCP Enabled. . . . . . . . . . . : No + Autoconfiguration Enabled . . . . : Yes + IPv4 Address. . . . . . . . . . . : 172.20.223.70(Preferred) + Subnet Mask . . . . . . . . . . . : 255.255.255.255 + Default Gateway . . . . . . . . . : 0.0.0.0 + DHCPv6 IAID . . . . . . . . . . . : 553799745 + DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-20-AF-7B-22-D4-81-D7-C4-72-74 + DNS Servers . . . . . . . . . . . : 172.20.20.11 + 172.20.20.12 + NetBIOS over Tcpip. . . . . . . . : Enabled diff --git a/documentation/images/OpenDisSurferDude.png b/documentation/images/OpenDisSurferDude.png new file mode 100644 index 0000000000000000000000000000000000000000..f9e558c33c4af10580a9faaef260c18325715903 Binary files /dev/null and b/documentation/images/OpenDisSurferDude.png differ diff --git a/examples/build.xml b/examples/build.xml index 78b29aff01d08f569be848887add3f7004143e54..65e2469d01f5930d5f9b688147cf14f4b590a729 100644 --- a/examples/build.xml +++ b/examples/build.xml @@ -8,7 +8,7 @@ <!-- You can turn off the Compile on Save (or Deploy on Save) setting --> <!-- in the project's Project Properties dialog box.--> -<project name="Networked_Graphics_MV3500_examples" default="default" basedir="."> +<project name="MV3500 examples" default="default" basedir="."> <description>Builds, tests, and runs the project Networked Graphics MV3500 examples.</description> <import file="nbproject/build-impl.xml"/> diff --git a/examples/nbproject/build-impl.xml b/examples/nbproject/build-impl.xml index a597975468383822a61c2c6b556867585e301696..08f4fec2a5ed8aecef43418dff61d54eb2b890ea 100644 --- a/examples/nbproject/build-impl.xml +++ b/examples/nbproject/build-impl.xml @@ -154,18 +154,6 @@ is divided into following sections: <istrue value="${not.archive.disabled}"/> </or> </condition> - <condition property="do.mkdist"> - <and> - <isset property="do.archive"/> - <isset property="libs.CopyLibs.classpath"/> - <not> - <istrue value="${mkdist.disabled}"/> - </not> - <not> - <istrue value="${modules.supported.internal}"/> - </not> - </and> - </condition> <condition property="do.archive+manifest.available"> <and> <isset property="manifest.available"/> @@ -379,11 +367,7 @@ is divided into following sections: <compilerarg value="-s"/> <compilerarg path="@{apgeneratedsrcdir}"/> <compilerarg line="${ap.proc.none.internal}"/> - <customize/>> - <compilerarg value="-Xlint:all"/> - <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap --> - <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac --> - <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> + <customize/> </javac> </sequential> </macrodef> @@ -427,9 +411,6 @@ is divided into following sections: <compilerarg path="@{apgeneratedsrcdir}"/> <compilerarg line="${ap.proc.none.internal}"/> <customize/> - <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap --> - <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac --> - <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> </javac> </sequential> </macrodef> @@ -465,9 +446,6 @@ is divided into following sections: <compilerarg line="${javac.profile.cmd.line.arg}"/> <compilerarg line="${javac.compilerargs}"/> <customize/> - <!-- http://ant.apache.org/manual/Tasks/javac.html#bootstrap --> - <!-- https://stackoverflow.com/questions/4134803/ant-passing-compilerarg-into-javac --> - <compilerarg value="-Xbootclasspath/p:${toString:lib.path.ref}"/> </javac> </sequential> </macrodef> @@ -1193,13 +1171,27 @@ is divided into following sections: <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/> </manifest> </target> - <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs"> + <target depends="init,compile" name="-check-do-mkdist"> + <condition property="do.mkdist"> + <and> + <isset property="do.archive"/> + <isset property="libs.CopyLibs.classpath"/> + <not> + <istrue value="${mkdist.disabled}"/> + </not> + <not> + <available file="${build.classes.dir}/module-info.class"/> + </not> + </and> + </condition> + </target> + <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-check-do-mkdist" if="do.mkdist" name="-do-jar-copylibs"> <j2seproject3:copylibs manifest="${tmp.manifest.file}"/> <echo level="info">To run this application from the command line without Ant, try:</echo> <property location="${dist.jar}" name="dist.jar.resolved"/> <echo level="info">java -jar "${dist.jar.resolved}"</echo> </target> - <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist"> + <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-check-do-mkdist" if="do.archive" name="-do-jar-jar" unless="do.mkdist"> <j2seproject1:jar manifest="${tmp.manifest.file}"/> <property location="${build.classes.dir}" name="build.classes.dir.resolved"/> <property location="${dist.jar}" name="dist.jar.resolved"/> diff --git a/examples/nbproject/project.properties b/examples/nbproject/project.properties index a7dc2db7ef8fef792b98ddfcdb28836db1d71427..690147e112a254f9104c5c4e96bd6c41854ff3d9 100644 --- a/examples/nbproject/project.properties +++ b/examples/nbproject/project.properties @@ -1,108 +1,107 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.title=Networked Graphics MV3500 examples -application.vendor=don -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.modulepath=\ - ${run.modulepath} -debug.test.classpath=\ - ${run.test.classpath} -debug.test.modulepath=\ - ${run.test.modulepath} -# Files in build.classes.dir which should be excluded from distribution jar -dist.archive.excludes= -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/Networked_Graphics_MV3500_examples.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.commons-io-2.6.jar=../lib/commons-io-2.6.jar -file.reference.dis-enums-1.3.jar=../lib/dis-enums-1.3.jar -file.reference.guava-28.0-jre.jar=../lib/guava-28.0-jre.jar -file.reference.open-dis7-entities-all.jar=../lib/open-dis7-entities-all.jar -file.reference.open-dis7-java.jar=../lib/open-dis7-java.jar -file.reference.open-dis7-javadoc.jar=../lib/open-dis7-javadoc.jar -file.reference.open-dis7-source.jar=../lib/open-dis7-source.jar -file.reference.open-dis_4.16.jar=../lib/open-dis_4.16.jar -includes=** -jar.compress=false -javac.classpath=\ - ${file.reference.open-dis7-entities-all.jar}:\ - ${file.reference.open-dis7-java.jar}:\ - ${file.reference.open-dis7-javadoc.jar}:\ - ${file.reference.open-dis7-source.jar}:\ - ${file.reference.commons-io-2.6.jar}:\ - ${file.reference.guava-28.0-jre.jar}:\ - ${file.reference.open-dis_4.16.jar}:\ - ${file.reference.dis-enums-1.3.jar} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.external.vm=true -javac.modulepath= -javac.processormodulepath= -javac.processorpath=\ - ${javac.classpath} -javac.source=1.8 -javac.target=1.8 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javac.test.modulepath=\ - ${javac.modulepath} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.html5=false -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.reference.open-dis7-java.jar=../lib/open-dis7-javadoc.jar -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -jlink.launcher=false -jlink.launcher.name=Networked_Graphics_MV3500_examples -main.class=TcpExamples.TcpExample1Telnet -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project. -# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. -# To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs= -run.modulepath=\ - ${javac.modulepath} -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -run.test.modulepath=\ - ${javac.test.modulepath} -source.encoding=UTF-8 -source.reference.open-dis7-java.jar=../lib/open-dis7-source.jar -src.dir=src +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.desc=Example programs provided as part of NPS course Networked Graphics MV3500. This course is an introduction to network communications in simulation applications. Topics include an introduction to the TCP/IP protocol stack; TCP/IP socket communications, including TCP, UDP, and multicast; and protocol design issues, with emphasis on Distributed Interactive Simulation (DIS) Protocol and High Level Architecture (HLA). Course emphasis is on creation and testing of network programming network code and web-browser applications. +application.homepage=https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/examples +application.splash=..\\..\\NetworkedGraphicsMV3500\\documentation\\images\\OpenDisSurferDude.png +application.title=NPS Networked Graphics MV3500 examples +application.vendor=Don Brutzman +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.modulepath=\ + ${run.modulepath} +debug.test.classpath=\ + ${run.test.classpath} +debug.test.modulepath=\ + ${run.test.modulepath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Networked_Graphics_MV3500_examples.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.commons-io-2.6.jar=../lib/commons-io-2.6.jar +file.reference.dis-enums-1.3.jar=../lib/dis-enums-1.3.jar +file.reference.guava-28.0-jre.jar=../lib/guava-28.0-jre.jar +file.reference.open-dis7-enumerations-classes.jar=../lib/open-dis7-enumerations-classes.jar +file.reference.open-dis7-pdus-classes.jar=../lib/open-dis7-pdus-classes.jar +file.reference.open-dis_4.16.jar=../lib/open-dis_4.16.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.open-dis7-enumerations-classes.jar}:\ + ${file.reference.open-dis7-pdus-classes.jar}:\ + ${file.reference.commons-io-2.6.jar}:\ + ${file.reference.guava-28.0-jre.jar}:\ + ${file.reference.open-dis_4.16.jar}:\ + ${file.reference.dis-enums-1.3.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=true +javac.modulepath= +javac.processormodulepath= +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.modulepath=\ + ${javac.modulepath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=true +javadoc.encoding=${source.encoding} +javadoc.html5=false +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.reference.open-dis7-enumerations-classes.jar=../lib/open-dis7-enumerations-javadoc.jar +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle=NPS Networked Graphics MV3500 Examples +jlink.launcher=false +jlink.launcher.name=Networked_Graphics_MV3500_examples +main.class=TcpExamples.TcpExample1Telnet +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.modulepath=\ + ${javac.modulepath} +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +run.test.modulepath=\ + ${javac.test.modulepath} +source.encoding=UTF-8 +source.reference.open-dis7-enumerations-classes.jar=../lib/open-dis7-enumerations-source.jar +src.dir=src diff --git a/examples/nbproject/project.xml b/examples/nbproject/project.xml index 58b9ae9e8aa001602af580934ab76e3b3120d5fc..17777b64b50917288d0955fa040b8ad779b80be8 100644 --- a/examples/nbproject/project.xml +++ b/examples/nbproject/project.xml @@ -12,7 +12,9 @@ <spellchecker-wordlist xmlns="http://www.netbeans.org/ns/spellchecker-wordlist/1"> <word>classpath</word> <word>CourseExamples</word> + <word>deserialization</word> <word>localhost</word> + <word>marshalling</word> <word>multicast</word> <word>Netbeans</word> <word>netcat</word> diff --git a/examples/src/HttpServletExamples/JavaServletArchitecture.pdf b/examples/src/HttpServletExamples/JavaServletArchitecture.pdf index 236c662b9c433cb23867a728adef739676412211..b4471ff80a3cb8f629f2181894c5d8ea46f07aec 100644 Binary files a/examples/src/HttpServletExamples/JavaServletArchitecture.pdf and b/examples/src/HttpServletExamples/JavaServletArchitecture.pdf differ diff --git a/examples/src/HttpServletExamples/JavaServletArchitecture.png b/examples/src/HttpServletExamples/JavaServletArchitecture.png index 6397123bd2d2f528c79b8897c9a4cdbf85962727..b0b336460bdcf2e0a7bebf6e3d07f570034f19f8 100644 Binary files a/examples/src/HttpServletExamples/JavaServletArchitecture.png and b/examples/src/HttpServletExamples/JavaServletArchitecture.png differ diff --git a/examples/src/HttpServletExamples/JavaServletArchitecture.vsdx b/examples/src/HttpServletExamples/JavaServletArchitecture.vsdx index f7c1df983ec0fc59aa767beb67dd6c9c0a331af6..5492753a1ceaf505e0d7837434ff9ff0011a8324 100644 Binary files a/examples/src/HttpServletExamples/JavaServletArchitecture.vsdx and b/examples/src/HttpServletExamples/JavaServletArchitecture.vsdx differ diff --git a/examples/src/OpenDis4Examples/EspduReceiver.java b/examples/src/OpenDis4Examples/EspduReceiver.java index 036477c953c41cf14a02136981a4c4275e9c651a..d34a6d60bbad03fba7e9a7b4db4755547014d3fb 100644 --- a/examples/src/OpenDis4Examples/EspduReceiver.java +++ b/examples/src/OpenDis4Examples/EspduReceiver.java @@ -30,7 +30,7 @@ public class EspduReceiver public static void main(String args[]) { - System.out.println("DisExamples.EspduReceiver started..."); + System.out.println("OpenDis4Examples.EspduReceiver started..."); MulticastSocket socket; DatagramPacket packet; @@ -75,7 +75,7 @@ public class EspduReceiver } // End try catch (IOException e) { - System.out.println("Problem with DisExamples.EspduReceiver, see exception trace:"); + System.out.println("Problem with OpenDis4Examples.EspduReceiver, see exception trace:"); System.out.println(e); } } // end main diff --git a/examples/src/OpenDis4Examples/EspduSender.java b/examples/src/OpenDis4Examples/EspduSender.java index 078cd1b3399633589b67ab38d4bada72fc28b3fb..dd0c8eeec4164f60ca5a2b83998ab411d5a6a22b 100644 --- a/examples/src/OpenDis4Examples/EspduSender.java +++ b/examples/src/OpenDis4Examples/EspduSender.java @@ -45,7 +45,7 @@ public class EspduSender { */ public static void main(String args[]) { - System.out.println("DisExamples.EspduSender started... send " + NUMBER_TO_SEND + " ESPDUs, initial index=0"); + System.out.println("OpenDis4Examples.EspduSender started... send " + NUMBER_TO_SEND + " ESPDUs, initial index=0"); /** * an entity state pdu */ @@ -263,7 +263,7 @@ public class EspduSender { } catch (IOException | InterruptedException e) { - System.out.println("Problem with DisExamples.EspduSender, see exception trace:"); + System.out.println("Problem with OpenDis4Examples.EspduSender, see exception trace:"); System.out.println(e); } } @@ -315,7 +315,7 @@ public class EspduSender { } catch (SocketException e) { - System.out.println("Problem with DisExamples.EspduSender.getBroadcastAddresses(), see exception trace:"); + System.out.println("Problem with OpenDis4Examples.EspduSender.getBroadcastAddresses(), see exception trace:"); System.out.println(e); } return broadcastAddresses; diff --git a/examples/src/OpenDis4Examples/PduReceiver.java b/examples/src/OpenDis4Examples/PduReceiver.java index 77923859df15cb83b5fa61e2189ccb765ef2f1fb..ab7161154619af3dc3588d28659188cc4a8bd71a 100644 --- a/examples/src/OpenDis4Examples/PduReceiver.java +++ b/examples/src/OpenDis4Examples/PduReceiver.java @@ -23,7 +23,7 @@ public class PduReceiver try { - System.out.println("DisExamples.PduReceiver started..."); + System.out.println("OpenDis4Examples.PduReceiver started..."); socket = new MulticastSocket (MULTICAST_PORT); address = InetAddress.getByName(MULTICAST_GROUP); socket.joinGroup(address); @@ -61,12 +61,12 @@ public class PduReceiver } catch (IOException e) { - System.out.println("Problem with DisExamples.PduReceiver, see exception trace:"); + System.out.println("Problem with OpenDis4Examples.PduReceiver, see exception trace:"); System.out.println(e); } finally { - System.out.println("DisExamples.PduReceiver complete."); + System.out.println("OpenDis4Examples.PduReceiver complete."); } } } diff --git a/examples/src/OpenDis4Examples/PduSender.java b/examples/src/OpenDis4Examples/PduSender.java index 63b17f128756e2422f70137a5c58fdc0e6d4bae5..6767f24044f4ead5bffcaf01217c126c23b1f321 100644 --- a/examples/src/OpenDis4Examples/PduSender.java +++ b/examples/src/OpenDis4Examples/PduSender.java @@ -44,7 +44,7 @@ public class PduSender public void run() { - System.out.println("DisExamples.PduSender started..."); + System.out.println("OpenDis4Examples.PduSender started..."); try { List<Pdu> generatedPdusList = new ArrayList<>(); diff --git a/examples/src/OpenDis7Examples/AllPduReceiver.java b/examples/src/OpenDis7Examples/AllPduReceiver.java index c2ad0f3b89eeeddbf8522d69587640ff2a9b58ee..fca670c79803bdb31e81bcdf6569dd3b4f93e135 100644 --- a/examples/src/OpenDis7Examples/AllPduReceiver.java +++ b/examples/src/OpenDis7Examples/AllPduReceiver.java @@ -3,15 +3,15 @@ package OpenDis7Examples; import java.net.*; import java.io.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; import edu.nps.moves.dis7.utilities.PduFactory; import java.util.ArrayList; public class AllPduReceiver { - public static final int DEFAULT_MULTICAST_PORT = AllPduSender.DEFAULT_MULTICAST_PORT; public static final String DEFAULT_MULTICAST_ADDRESS = AllPduSender.DEFAULT_MULTICAST_ADDRESS; + public static final int DEFAULT_MULTICAST_PORT = AllPduSender.DEFAULT_MULTICAST_PORT; public static final boolean USE_FAST_ESPDU = false; public static void main(String args[]) @@ -22,14 +22,14 @@ public class AllPduReceiver DatagramPacket packet; try { - System.out.println("DisExamplesOpenDis7.AllPduReceiver started..."); + System.out.println("OpenDis7Examples.AllPduReceiver started..."); if (args.length == 2) { - socket = new MulticastSocket(Integer.parseInt(args[0])); - address = InetAddress.getByName(args[1]); + address = InetAddress.getByName(args[0]); + socket = new MulticastSocket(Integer.parseInt(args[1])); } else { - System.out.println("Usage: AllPduReceiver <port> <multicast group>"); - System.out.println("Default: AllPduReceiver " + DEFAULT_MULTICAST_PORT + " " + DEFAULT_MULTICAST_ADDRESS); + System.out.println("Usage: AllPduReceiver <multicast group> <port>"); + System.out.println("Default: AllPduReceiver " + DEFAULT_MULTICAST_ADDRESS + " " + DEFAULT_MULTICAST_PORT); socket = new MulticastSocket(DEFAULT_MULTICAST_PORT); address = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); } @@ -45,7 +45,7 @@ public class AllPduReceiver socket.receive(packet); - Pdu pdu = factory.createPdu(packet.getData()); + Pdu pdu = factory.createPdu(packet.getData()); // packet.getData() returns byte[] array data buffer if (pdu != null) { DISPDUType currentPduType = pdu.getPduType(); //short currentPduType = pdu.getPduType(); @@ -54,16 +54,16 @@ public class AllPduReceiver String currentPduFamilyName = pdu.getClass().getSuperclass().getSimpleName(); StringBuilder message = new StringBuilder(); + message.append(DisTime.timeStampToString(pdu.getTimestamp()) + " "); message.append("received DIS PDU "); + String currentPduTypePadded = String.format("%-34s", currentPduType); // - indicates right padding of whitespace + message.append(" " ).append(currentPduTypePadded); if (currentPduType.getValue() < 10) message.append(" "); // column spacing - message.append(currentPduType.getValue()); - String currentPduTypePadded = String.format("%-34s", currentPduType); // - indicates right padding of whitespace - message.append(" " ).append(currentPduTypePadded); - String currentPduTypeNamePadded = String.format("%-49s", currentPduTypeName); // - indicates right padding of whitespace - message.append(" of type ").append(currentPduTypeNamePadded); // package.class name - message.append(" (protocolFamily ").append(currentProtocolFamilyID); - // message.append(" ").append(currentPduFamilyName); // class name is also available +// String currentPduTypeNamePadded = String.format("%-49s", currentPduTypeName); // - indicates right padding of whitespace +// message.append(" of type ").append(currentPduTypeNamePadded); // package.class name + message.append(" (").append(currentProtocolFamilyID); +// message.append(" ").append(currentPduFamilyName); // class name is also available message.append(")"); System.out.println(message.toString()); @@ -72,11 +72,14 @@ public class AllPduReceiver case COMMENT: CommentPdu commentPdu = (CommentPdu)pdu; // cast to precise type ArrayList<VariableDatum> payloadList = (ArrayList)commentPdu.getVariableDatums(); + if (!payloadList.isEmpty()) + System.out.print (" messages: "); for (VariableDatum variableDatum : payloadList) { String nextComment = new String(variableDatum.getVariableDatumValue()); // convert byte[] to String - System.out.println("\"" + nextComment + "\""); + System.out.print (" \"" + nextComment + "\""); } + System.out.println(); } } else @@ -84,11 +87,11 @@ public class AllPduReceiver } } catch (IOException e) { - System.out.println("Problem with DisExamplesOpenDis7.AllPduReceiver, see exception trace:"); + System.out.println("Problem with OpenDis7Examples.AllPduReceiver, see exception trace:"); System.out.println(e); } finally { - System.out.println("DisExamplesOpenDis7.AllPduReceiver complete."); + System.out.println("OpenDis7Examples.AllPduReceiver complete."); } } } diff --git a/examples/src/OpenDis7Examples/AllPduSender.java b/examples/src/OpenDis7Examples/AllPduSender.java index 1d01685d32e62a81beee06b2ed21538ee265caa0..5bd043d2272534d3963858604167bf136fff4d13 100755 --- a/examples/src/OpenDis7Examples/AllPduSender.java +++ b/examples/src/OpenDis7Examples/AllPduSender.java @@ -4,11 +4,11 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.*; /** - * This is an example that sends many/most types of PDUs. Useful for testing standards + * This is an application example that sends all types of PDUs. Useful for testing standards * compliance or getting a full set of PDUs. It also writes the generated PDUs to an XML file. * Adapted from OpenDIS library example package edu.nps.moves.examples * @@ -18,450 +18,477 @@ import edu.nps.moves.dis7.enumerations.*; public class AllPduSender { /** Default multicast group address we send on. */ - public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; + public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; // PduRecorder "225.4.5.6"; // /** Default multicast port used, matches Wireshark DIS capture default */ public static final int DEFAULT_MULTICAST_PORT = 3000; - private int port; - InetAddress multicastAddress; - - public AllPduSender(int port, String multicast) { + /** Duration in milliseconds, set to 0 to avoid pausing between PDU sends */ + private long THREAD_SLEEP_INTERVAL = 0; + + /** Number of complete loops to perform */ + private int SEND_LOOPS_TO_PERFORM = 1; + + private static InetAddress multicastAddress; + private static int port; + + public AllPduSender(String newMulticastAddress, int newMulticastPort) { + this.port = DEFAULT_MULTICAST_PORT; try { - this.port = port; - multicastAddress = InetAddress.getByName(multicast); + multicastAddress = InetAddress.getByName(newMulticastAddress); if (!multicastAddress.isMulticastAddress()) { - System.out.println("Not a multicast address: " + multicast); + System.out.println("Not a multicast address: " + newMulticastAddress); } + this.port = newMulticastPort; } catch (UnknownHostException e) { System.out.println("Unable to open socket: " + e); } } + @SuppressWarnings("SleepWhileInLoop") public int run() { - System.out.println("DisExamplesOpenDis7.AllPduSender started..."); - try + System.out.println("OpenDis7Examples.AllPduSender started..."); + if (SEND_LOOPS_TO_PERFORM != 1) { - System.out.println("Generate PDUs and note issues, if any..."); - List<Pdu> generatedPdusList = new ArrayList<>(); + float waitIntervalSeconds = ((float)THREAD_SLEEP_INTERVAL / 1000); + float loopIntervalSeconds = ((float)THREAD_SLEEP_INTERVAL / 1000) * 72; // 72 PDUs + float totalDurationSeconds = loopIntervalSeconds * SEND_LOOPS_TO_PERFORM ; + System.out.println("... THREAD_SLEEP_INTERVAL = " + THREAD_SLEEP_INTERVAL + " milliseconds = " + waitIntervalSeconds + " seconds"); + System.out.print ("... running for "); + if (SEND_LOOPS_TO_PERFORM > 1) + System.out.print (SEND_LOOPS_TO_PERFORM + " loops, "); + if (THREAD_SLEEP_INTERVAL > 0) + System.out.println("expected loop interval = " + loopIntervalSeconds + " seconds, total duration = " + + totalDurationSeconds + " seconds = " + (totalDurationSeconds/60.0) + " minutes"); + } + + System.out.println("Generate list of all PDU types and note issues, if any..."); + List<Pdu> generatedPdusList = new ArrayList<>(); + + for (int i = 0; i < SEND_LOOPS_TO_PERFORM; i++) { + + try { + + // Loop through all the enumerated PDU types, create a PDU for each type, + // add that PDU to generatedPdusList, then send each one + for (DISPDUType pdu : DISPDUType.values()) + { + // System.out.println("PDU " + pdu.getValue() + " " + pdu.name() + " " + pdu.getDescription()); // diagnostic + + Pdu aPdu = null; // edu.​nps.​moves7.​dis.PDU superclass for all PDUs, in preparation for custom assignment + + try { + switch (pdu) // using enumeration values from edu.​nps.​moves.​dis7.​enumerations.​DISPDUType + { + // each case value is DISPDUType + case OTHER: // 0 + System.out.println ("*** Note: DISPDUType." + pdu.name() + "=" + pdu.getValue() + " not supported"); // TODO why was this received? + break; // nothing to send + + case ENTITY_STATE: // 1 + aPdu = new EntityStatePdu(); + + EntityStatePdu espdu = (EntityStatePdu) aPdu; + EntityMarking entityMarking = new EntityMarking (); + entityMarking.setCharacters("AllPduSender".getBytes()); //entityMarking.setCharacters(Byte.valueOf("0")); // 11 characters max? + + espdu.setMarking(entityMarking); + Vector3Double espduLocation = new Vector3Double(); + espduLocation.setX(1.0); + espduLocation.setY(2.0); + espduLocation.setZ(3.0); + espdu.setEntityLocation(espduLocation); + // it is important to identify questions as you think of them + // TODO how to set azimuth, i.e. course direction over ground? + break; + + case FIRE: // 2 + aPdu = new FirePdu(); + break; + + case DETONATION: // 3 + aPdu = new DetonationPdu(); + break; + + case COLLISION: // 4 + aPdu = new CollisionPdu(); + break; + + case SERVICE_REQUEST: // 5 + aPdu = new ServiceRequestPdu(); + break; + + case RESUPPLY_OFFER: // 6 + aPdu = new ResupplyOfferPdu(); + break; + + case RESUPPLY_RECEIVED: // 7 + aPdu = new ResupplyReceivedPdu(); + break; + + case RESUPPLY_CANCEL: //8 + aPdu = new ResupplyCancelPdu(); + break; + + case REPAIR_COMPLETE: // 9 + aPdu = new RepairCompletePdu(); + break; + + case REPAIR_RESPONSE: // 10 + aPdu = new RepairResponsePdu(); + break; + + case CREATE_ENTITY: // 11 + aPdu = new CreateEntityPdu(); + break; + + case REMOVE_ENTITY: // 12 + aPdu = new RemoveEntityPdu(); + break; + + case START_RESUME: // 13 + aPdu = new StartResumePdu(); + break; + + case STOP_FREEZE: // 14 + aPdu = new StopFreezePdu(); + break; + + case ACKNOWLEDGE: // 15 + aPdu = new AcknowledgePdu(); + break; + + case ACTION_REQUEST: // 16 + aPdu = new ActionRequestPdu(); + break; + + case ACTION_RESPONSE: // 17 + aPdu = new ActionResponsePdu(); + break; + + case DATA_QUERY: // 18 + aPdu = new DataQueryPdu(); + break; + + case SET_DATA: // 19 + aPdu = new SetDataPdu(); + break; + + case DATA: // 20 + aPdu = new DataPdu(); + break; + + case EVENT_REPORT: // 21 + aPdu = new EventReportPdu(); + break; + + case ELECTROMAGNETIC_EMISSION: // 23 + aPdu = new ElectromagneticEmissionPdu(); + break; + + case DESIGNATOR: // 24 + aPdu = new DesignatorPdu(); + break; + + case TRANSMITTER: // 25 + aPdu = new TransmitterPdu(); + break; + + case SIGNAL: // 26 + aPdu = new SignalPdu(); + break; - // Loop through all the enumerated PDU types, create a PDU for each type, - // add that PDU to generatedPdusList, and send each one - for (DISPDUType pdu : DISPDUType.values()) - { -// System.out.println("PDU " + pdu.getValue() + " " + pdu.name() + " " + pdu.getDescription()); // diagnostic + case RECEIVER: // 27 + aPdu = new ReceiverPdu(); + break; - Pdu aPdu = null; // edu.​nps.​moves7.​dis.PDU superclass for all PDUs, in preparation for custom assignment - - try { - switch (pdu) // using enumeration values from edu.​nps.​moves.​dis7.​enumerations.​DISPDUType - { - // each case value is DISPDUType - case OTHER: // 0 - System.out.println ("*** Note: DISPDUType." + pdu.name() + "=" + pdu.getValue() + " not supported"); // TODO why was this received? - break; // nothing to send - - case ENTITY_STATE: // 1 - aPdu = new EntityStatePdu(); - - EntityStatePdu espdu = (EntityStatePdu) aPdu; - EntityMarking entityMarking = new EntityMarking (); - entityMarking.setCharacters("AllPduSender".getBytes()); //entityMarking.setCharacters(Byte.valueOf("0")); // 11 characters max? - - espdu.setMarking(entityMarking); - Vector3Double espduLocation = new Vector3Double(); - espduLocation.setX(1.0); - espduLocation.setY(2.0); - espduLocation.setZ(3.0); - espdu.setEntityLocation(espduLocation); - // it is important to identify questions as you think of them - // TODO how to set azimuth, i.e. course direction over ground? - break; - - case FIRE: // 2 - aPdu = new FirePdu(); - break; - - case DETONATION: // 3 - aPdu = new DetonationPdu(); - break; - - case COLLISION: // 4 - aPdu = new CollisionPdu(); - break; - - case SERVICE_REQUEST: // 5 - aPdu = new ServiceRequestPdu(); - break; - - case RESUPPLY_OFFER: // 6 - aPdu = new ResupplyOfferPdu(); - break; - - case RESUPPLY_RECEIVED: // 7 - aPdu = new ResupplyReceivedPdu(); - break; - - case RESUPPLY_CANCEL: //8 - aPdu = new ResupplyCancelPdu(); - break; - - case REPAIR_COMPLETE: // 9 - aPdu = new RepairCompletePdu(); - break; - - case REPAIR_RESPONSE: // 10 - aPdu = new RepairResponsePdu(); - break; - - case CREATE_ENTITY: // 11 - aPdu = new CreateEntityPdu(); - break; - - case REMOVE_ENTITY: // 12 - aPdu = new RemoveEntityPdu(); - break; - - case START_RESUME: // 13 - aPdu = new StartResumePdu(); - break; - - case STOP_FREEZE: // 14 - aPdu = new StopFreezePdu(); - break; - - case ACKNOWLEDGE: // 15 - aPdu = new AcknowledgePdu(); - break; - - case ACTION_REQUEST: // 16 - aPdu = new ActionRequestPdu(); - break; - - case ACTION_RESPONSE: // 17 - aPdu = new ActionResponsePdu(); - break; - - case DATA_QUERY: // 18 - aPdu = new DataQueryPdu(); - break; - - case SET_DATA: // 19 - aPdu = new SetDataPdu(); - break; - - case DATA: // 20 - aPdu = new DataPdu(); - break; - - case EVENT_REPORT: // 21 - aPdu = new EventReportPdu(); - break; - - case ELECTROMAGNETIC_EMISSION: // 23 - aPdu = new ElectromagneticEmissionPdu(); - break; - - case DESIGNATOR: // 24 - aPdu = new DesignatorPdu(); - break; - - case TRANSMITTER: // 25 - aPdu = new TransmitterPdu(); - break; - - case SIGNAL: // 26 - aPdu = new SignalPdu(); - break; + case IDENTIFICATION_FRIEND_OR_FOE: // 28 + aPdu = new IdentificationFriendOrFoePdu(); + break; + + case UNDERWATER_ACOUSTIC: // 29 + aPdu = new UnderwaterAcousticPdu(); + break; - case RECEIVER: // 27 - aPdu = new ReceiverPdu(); - break; + case SUPPLEMENTAL_EMISSION_ENTITY_STATE: // 30 + aPdu = new SupplementalEmissionEntityStatePdu(); + break; - case IDENTIFICATION_FRIEND_OR_FOE: // 28 - aPdu = new IdentificationFriendOrFoePdu(); - break; + case INTERCOM_SIGNAL: // 31 + aPdu = new IntercomSignalPdu(); + break; - case UNDERWATER_ACOUSTIC: // 29 - aPdu = new UnderwaterAcousticPdu(); - break; + case INTERCOM_CONTROL: // 32 + aPdu = new IntercomControlPdu(); + break; - case SUPPLEMENTAL_EMISSION_ENTITY_STATE: // 30 - aPdu = new SupplementalEmissionEntityStatePdu(); - break; + case AGGREGATE_STATE: // 33 + aPdu = new AggregateStatePdu(); + break; - case INTERCOM_SIGNAL: // 31 - aPdu = new IntercomSignalPdu(); - break; + case ISGROUPOF: // 34 + aPdu = new IsGroupOfPdu(); + break; - case INTERCOM_CONTROL: // 32 - aPdu = new IntercomControlPdu(); - break; + case TRANSFER_OWNERSHIP: // 35 + aPdu = new TransferOwnershipPdu(); + break; - case AGGREGATE_STATE: // 33 - aPdu = new AggregateStatePdu(); - break; + case ISPARTOF: // 36 + aPdu = new IsPartOfPdu(); + break; - case ISGROUPOF: // 34 - aPdu = new IsGroupOfPdu(); - break; + case MINEFIELD_STATE: // 37 + aPdu = new MinefieldStatePdu(); + break; - case TRANSFER_OWNERSHIP: // 35 - aPdu = new TransferOwnershipPdu(); - break; + case MINEFIELD_QUERY: // 38 + aPdu = new MinefieldQueryPdu(); + break; - case ISPARTOF: // 36 - aPdu = new IsPartOfPdu(); - break; + case MINEFIELD_DATA: // 39 + aPdu = new MinefieldDataPdu(); + break; - case MINEFIELD_STATE: // 37 - aPdu = new MinefieldStatePdu(); - break; + case MINEFIELD_RESPONSE_NACK: // 40 + aPdu = new MinefieldResponseNACKPdu(); + break; - case MINEFIELD_QUERY: // 38 - aPdu = new MinefieldQueryPdu(); - break; + case ENVIRONMENTAL_PROCESS: // 41 + aPdu = new EnvironmentalProcessPdu(); + break; - case MINEFIELD_DATA: // 39 - aPdu = new MinefieldDataPdu(); - break; + case GRIDDED_DATA: // 42 + aPdu = new GriddedDataPdu(); + break; - case MINEFIELD_RESPONSE_NACK: // 40 - aPdu = new MinefieldResponseNACKPdu(); - break; + case POINT_OBJECT_STATE: // 43 + aPdu = new PointObjectStatePdu(); + break; - case ENVIRONMENTAL_PROCESS: // 41 - aPdu = new EnvironmentalProcessPdu(); - break; + case LINEAR_OBJECT_STATE: // 44 + aPdu = new LinearObjectStatePdu(); + break; - case GRIDDED_DATA: // 42 - aPdu = new GriddedDataPdu(); - break; + case AREAL_OBJECT_STATE: // 45 + aPdu = new ArealObjectStatePdu(); + break; - case POINT_OBJECT_STATE: // 43 - aPdu = new PointObjectStatePdu(); - break; + case TIME_SPACE_POSITION_INFORMATION: // 46 + aPdu = new TimeSpacePositionInformationPdu(); + break; - case LINEAR_OBJECT_STATE: // 44 - aPdu = new LinearObjectStatePdu(); - break; + case APPEARANCE: // 47 + aPdu = new AppearancePdu(); + break; - case AREAL_OBJECT_STATE: // 45 - aPdu = new ArealObjectStatePdu(); - break; + case ARTICULATED_PARTS: // 48 + aPdu = new ArticulatedPartsPdu(); + break; - case TIME_SPACE_POSITION_INFORMATION: // 46 - aPdu = new TimeSpacePositionInformationPdu(); - break; + case LIVE_ENTITY_FIRE: // 49 + aPdu = new LiveEntityFirePdu(); + break; - case APPEARANCE: // 47 - aPdu = new AppearancePdu(); - break; + case LIVE_ENTITY_DETONATION: // 50 + aPdu = new LiveEntityDetonationPdu(); + break; - case ARTICULATED_PARTS: // 48 - aPdu = new ArticulatedPartsPdu(); - break; + case CREATE_ENTITY_RELIABLE: // 51 + aPdu = new CreateEntityReliablePdu(); + break; - case LIVE_ENTITY_FIRE: // 49 - aPdu = new LiveEntityFirePdu(); - break; - - case LIVE_ENTITY_DETONATION: // 50 - aPdu = new LiveEntityDetonationPdu(); - break; - - case CREATE_ENTITY_RELIABLE: // 51 - aPdu = new CreateEntityReliablePdu(); - break; - - case REMOVE_ENTITY_RELIABLE: // 52 - aPdu = new RemoveEntityReliablePdu(); - break; - - case START_RESUME_RELIABLE: // 53 - aPdu = new StartResumeReliablePdu(); - break; - - case STOP_FREEZE_RELIABLE: // 54 - aPdu = new StopFreezeReliablePdu(); - break; - - case ACKNOWLEDGE_RELIABLE: // 55 - aPdu = new AcknowledgeReliablePdu(); - break; - - case ACTION_REQUEST_RELIABLE: // 56 - aPdu = new ActionRequestReliablePdu(); - break; - - case ACTION_RESPONSE_RELIABLE: // 57 - aPdu = new ActionResponseReliablePdu(); - break; - - case DATA_QUERY_RELIABLE: // 58 - aPdu = new DataQueryReliablePdu(); - break; - - case SET_DATA_RELIABLE: // 59 - aPdu = new SetDataReliablePdu(); - break; - - case DATA_RELIABLE: // 60 - aPdu = new DataReliablePdu(); - break; - - case EVENT_REPORT_RELIABLE: // 61 - aPdu = new EventReportReliablePdu(); - break; - - case COMMENT_RELIABLE: // 62 - aPdu = new CommentReliablePdu(); - break; - - case RECORD_RELIABLE: // 63 - aPdu = new RecordReliablePdu(); - break; - - case SET_RECORD_RELIABLE: // 64 - aPdu = new SetRecordReliablePdu(); - break; - - case RECORD_QUERY_RELIABLE: // 65 - aPdu = new RecordQueryReliablePdu(); - break; - - case COLLISION_ELASTIC: // 66 - aPdu = new CollisionElasticPdu(); - break; - - case ENTITY_STATE_UPDATE: // 67 - aPdu = new EntityStateUpdatePdu(); - break; - - case DIRECTED_ENERGY_FIRE: // 68 - aPdu = new DirectedEnergyFirePdu(); - break; - - case ENTITY_DAMAGE_STATUS: // 69 - aPdu = new EntityDamageStatusPdu(); - break; - - case INFORMATION_OPERATIONS_ACTION: // 70 - aPdu = new InformationOperationsActionPdu(); - break; - - case INFORMATION_OPERATIONS_REPORT: // 71 - aPdu = new InformationOperationsReportPdu(); - break; - - case ATTRIBUTE: // 72 - aPdu = new AttributePdu(); - break; - - case COMMENT: - // aPdu = new CommentPdu(); // default for this switch logic - - // see Garrett Loffelman and Pete Severson's code for OpenDis version 4 example - // https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments/src/MV3500Cohort2018JulySeptember/projects/LoeffelmanSeverson - - CommentPdu newCommentPdu = new CommentPdu(); - ArrayList<VariableDatum> payloadList = new ArrayList<>(); - - ArrayList<String> commentsList = new ArrayList<>(); - commentsList.add("Hello CommentPDU"); - commentsList.add("Here is a second line of text in this comment."); - - if (!commentsList.isEmpty()) - System.out.println("Preparing CommentPDU:"); - - for (String comment : commentsList) - { - VariableDatum newVariableDatum = new VariableDatum(); - newVariableDatum.setVariableDatumValue (comment.getBytes()); // conversion - newVariableDatum.setVariableDatumLengthInBytes(comment.getBytes().length); // also available in bits, see spec and javadoc - // alternatively, you do not need to set this and the marshaller will figure it out from the byte array - // (see javadoc for VariableDatum.setVariableDatumLength()) - payloadList.add(newVariableDatum); - System.out.println(" \"" + comment + "\""); - } - newCommentPdu.setVariableDatums(payloadList); - - aPdu = newCommentPdu; // hand off for sending - break; - - default: - System.out.println("*** Warning: PDU " + pdu.getValue() + " " + pdu + " not supported, created or sent "); - - // code generation block for this class follows: -// System.out.println(" case " + pdu + ": // " + pdu.getValue()); -// System.out.println(" aPdu = new " + pdu.getDescription().replace(" ","").replace("-","").replace("/","") + -// "Pdu();"); -// System.out.println(" break;"); -// System.out.println(); + case REMOVE_ENTITY_RELIABLE: // 52 + aPdu = new RemoveEntityReliablePdu(); + break; + + case START_RESUME_RELIABLE: // 53 + aPdu = new StartResumeReliablePdu(); + break; + + case STOP_FREEZE_RELIABLE: // 54 + aPdu = new StopFreezeReliablePdu(); + break; + + case ACKNOWLEDGE_RELIABLE: // 55 + aPdu = new AcknowledgeReliablePdu(); + break; + + case ACTION_REQUEST_RELIABLE: // 56 + aPdu = new ActionRequestReliablePdu(); + break; + + case ACTION_RESPONSE_RELIABLE: // 57 + aPdu = new ActionResponseReliablePdu(); + break; + + case DATA_QUERY_RELIABLE: // 58 + aPdu = new DataQueryReliablePdu(); + break; + + case SET_DATA_RELIABLE: // 59 + aPdu = new SetDataReliablePdu(); + break; + + case DATA_RELIABLE: // 60 + aPdu = new DataReliablePdu(); + break; + + case EVENT_REPORT_RELIABLE: // 61 + aPdu = new EventReportReliablePdu(); + break; + + case COMMENT_RELIABLE: // 62 + aPdu = new CommentReliablePdu(); + break; + + case RECORD_RELIABLE: // 63 + aPdu = new RecordReliablePdu(); + break; + + case SET_RECORD_RELIABLE: // 64 + aPdu = new SetRecordReliablePdu(); + break; + + case RECORD_QUERY_RELIABLE: // 65 + aPdu = new RecordQueryReliablePdu(); + break; + + case COLLISION_ELASTIC: // 66 + aPdu = new CollisionElasticPdu(); + break; + + case ENTITY_STATE_UPDATE: // 67 + aPdu = new EntityStateUpdatePdu(); + break; + + case DIRECTED_ENERGY_FIRE: // 68 + aPdu = new DirectedEnergyFirePdu(); + break; + + case ENTITY_DAMAGE_STATUS: // 69 + aPdu = new EntityDamageStatusPdu(); + break; + + case INFORMATION_OPERATIONS_ACTION: // 70 + aPdu = new InformationOperationsActionPdu(); + break; + + case INFORMATION_OPERATIONS_REPORT: // 71 + aPdu = new InformationOperationsReportPdu(); + break; + + case ATTRIBUTE: // 72 + aPdu = new AttributePdu(); + break; + + case COMMENT: + // aPdu = new CommentPdu(); // default for this switch logic + + // see Garrett Loffelman and Pete Severson's code for OpenDis version 4 example + // https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/tree/master/assignments/src/MV3500Cohort2018JulySeptember/projects/LoeffelmanSeverson + + CommentPdu newCommentPdu = new CommentPdu(); + ArrayList<VariableDatum> payloadList = new ArrayList<>(); + ArrayList<String> commentsList = new ArrayList<>(); + commentsList.add("Hello CommentPDU"); + commentsList.add("Here is a second line of text in this comment."); + if (!commentsList.isEmpty()) + System.out.println("Preparing CommentPDU:"); + + for (String comment : commentsList) + { + VariableDatum newVariableDatum = new VariableDatum(); + newVariableDatum.setVariableDatumValue (comment.getBytes()); // conversion + newVariableDatum.setVariableDatumLengthInBytes(comment.getBytes().length); // also available in bits, see spec and javadoc + // alternatively, you do not need to set this and the marshaller will figure it out from the byte array + // (see javadoc for VariableDatum.setVariableDatumLength()) + payloadList.add(newVariableDatum); + System.out.println(" \"" + comment + "\""); + } + newCommentPdu.setVariableDatums(payloadList); + + aPdu = newCommentPdu; // hand off for sending + break; + + default: + System.out.println("*** Warning: PDU " + pdu.getValue() + " " + pdu + " not supported, created or sent "); + + // code generation block for this class follows: + // System.out.println(" case " + pdu + ": // " + pdu.getValue()); + // System.out.println(" aPdu = new " + pdu.getDescription().replace(" ","").replace("-","").replace("/","") + + // "Pdu();"); + // System.out.println(" break;"); + // System.out.println(); + } + if (aPdu != null) + { + generatedPdusList.add(aPdu); + } } - if (aPdu != null) + catch (Exception e) { - generatedPdusList.add(aPdu); - } - } - catch (Exception e) - { - System.out.print("Exception thrown for PDU " + pdu.getValue() + " " + pdu); - System.out.print(Arrays.toString(e.getStackTrace())); - // continue looping + System.out.print("Exception thrown for PDU " + pdu.getValue() + " " + pdu); + System.out.print(Arrays.toString(e.getStackTrace())); + // continue looping + } } - } - if (generatedPdusList.size() != 72) // TODO create an enumeration DISType.TOTAL_PDU_TYPES - System.out.println("Error: " + generatedPdusList.size() + " PDUs generated but 72 PDUs expected."); - - // Send the PDUs we created - System.out.println("Send the " + generatedPdusList.size() + " PDUs we created..."); + if (generatedPdusList.size() != 72) // TODO create an enumeration DISType.TOTAL_PDU_TYPES + System.out.println("Error: " + generatedPdusList.size() + " PDUs generated but 72 PDUs expected."); - InetAddress localMulticastAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); - MulticastSocket multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT); - multicastSocket.joinGroup(localMulticastAddress); - - // keep object instantiations outside of loops for best performance - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - byte[] buffer; - Pdu aPdu; - DatagramPacket packet; - - for (int idx = 0; idx < generatedPdusList.size(); idx++) - { - aPdu = generatedPdusList.get(idx); - try + // Send the PDUs we created + System.out.println("Send the " + generatedPdusList.size() + " PDUs we created..."); + + InetAddress localMulticastAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); + MulticastSocket multicastSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT); + multicastSocket.joinGroup(localMulticastAddress); + + // keep object instantiations outside of loops for best performance + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + byte[] buffer; + Pdu aPdu; + DatagramPacket packet; + + for (int idx = 0; idx < generatedPdusList.size(); idx++) { - aPdu.marshal(dos); - - buffer = baos.toByteArray(); - packet = new DatagramPacket(buffer, buffer.length, localMulticastAddress, DEFAULT_MULTICAST_PORT); - multicastSocket.send(packet); - String currentPduTypeValuePadded = String.format("%2s", aPdu.getPduType().getValue()); - String currentPduTypePadded = String.format("%-50s", aPdu.getPduType().toString()); // - indicates right padding of whitespace - System.out.print ("Sent DIS PDU " + currentPduTypeValuePadded + " " + currentPduTypePadded ); - System.out.println(" of type " + aPdu.getClass().getName()); - } - catch (Exception ex) { - System.out.println("Marshaling error" + ex); + aPdu = generatedPdusList.get(idx); + try + { + aPdu.marshal(dos); + + buffer = baos.toByteArray(); + packet = new DatagramPacket(buffer, buffer.length, localMulticastAddress, DEFAULT_MULTICAST_PORT); + multicastSocket.send(packet); + String currentPduTypeValuePadded = String.format("%2s", aPdu.getPduType().getValue()); + String currentPduTypePadded = String.format("%-50s", aPdu.getPduType().toString()); // - indicates right padding of whitespace + System.out.print ("Sent DIS PDU " + currentPduTypeValuePadded + " " + currentPduTypePadded ); + System.out.println(" of type " + aPdu.getClass().getName()); + + if (THREAD_SLEEP_INTERVAL > 0) + Thread.sleep(THREAD_SLEEP_INTERVAL); // pause for debugging + } + catch (Exception ex) { + System.out.println("Marshaling error" + ex); + } } } - // write the PDUs out to an XML file. - //PduContainer container = new PduContainer(); - //container.setPdus(generatedPdus); - //container.marshallToXml("examplePdus.xml"); - return generatedPdusList.size(); - } - catch (IOException e) - { - System.out.println(e); - return -1; - } + catch (IOException e) + { + System.out.println(e); + return -1; + } + } // end repetion loop + + // write the PDUs out to an XML file. + //PduContainer container = new PduContainer(); + //container.setPdus(generatedPdus); + //container.marshallToXml("examplePdus.xml"); + return generatedPdusList.size(); } public static void main(String args[]) @@ -471,16 +498,18 @@ public class AllPduSender if (args.length == 2) { - allPduSender = new AllPduSender(Integer.parseInt(args[0]), args[1]); + allPduSender = new AllPduSender(args[0], Integer.parseInt(args[1])); + System.out.println("Usage: AllPduSender <multicast group> <port>"); + System.out.println("Actual: AllPduSender " + multicastAddress.getHostAddress() + " " + port); totalSentPdus = allPduSender.run(); } else { - System.out.println("Usage: AllPduSender <port> <multicast group>"); - System.out.println("Default: AllPduSender " + DEFAULT_MULTICAST_PORT + " " + DEFAULT_MULTICAST_ADDRESS); - allPduSender = new AllPduSender(DEFAULT_MULTICAST_PORT, DEFAULT_MULTICAST_ADDRESS); + System.out.println("Usage: AllPduSender <multicast group> <port>"); + System.out.println("Default: AllPduSender " + DEFAULT_MULTICAST_ADDRESS + " " + DEFAULT_MULTICAST_PORT); + allPduSender = new AllPduSender(DEFAULT_MULTICAST_ADDRESS, DEFAULT_MULTICAST_PORT); totalSentPdus = allPduSender.run(); } - System.out.println("DisExamplesOpenDis7.AllPduSender complete, sent " + totalSentPdus + " PDUs total."); + System.out.println("OpenDis7Examples.AllPduSender complete, sent " + totalSentPdus + " PDUs total."); } } diff --git a/examples/src/OpenDis7Examples/AllPduSenderLog.txt b/examples/src/OpenDis7Examples/AllPduSenderLog.txt index 6ebd47195d57181a4a0778d898693c850745daf8..0fb9babe68333bcaf60edef633bf78d6fdccdc20 100644 --- a/examples/src/OpenDis7Examples/AllPduSenderLog.txt +++ b/examples/src/OpenDis7Examples/AllPduSenderLog.txt @@ -1,90 +1,93 @@ -Invocation instructions: -1. run or debug AllPduSender.java - -Program response: - -=================================================== - +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/AllPduSender.java -Drun.class=OpenDis7Examples.AllPduSender run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +Note: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\src\OpenDis7Examples\AllPduSender.java uses or overrides a deprecated API. +Note: Recompile with -Xlint:deprecation for details. +compile-single: +run-single: Usage: AllPduSender <port> <multicast group> -Default: AllPduSender 3000 239.1.2.3 -DisExamplesOpenDis7.AllPduSender started... -Generate PDUs and note issues, if any... +Default: AllPduSender 3000 225.4.5.6 +OpenDis7Examples.AllPduSender started... +Generate list of all PDU types and note issues, if any... *** Note: DISPDUType.OTHER=0 not supported Preparing CommentPDU: "Hello CommentPDU" "Here is a second line of text in this comment." Send the 72 PDUs we created... -Sent DIS PDU 1 DISPDUType: ENTITY_STATE: 1 of type edu.nps.moves.dis7.EntityStatePdu -Sent DIS PDU 2 DISPDUType: FIRE: 2 of type edu.nps.moves.dis7.FirePdu -Sent DIS PDU 3 DISPDUType: DETONATION: 3 of type edu.nps.moves.dis7.DetonationPdu -Sent DIS PDU 4 DISPDUType: COLLISION: 4 of type edu.nps.moves.dis7.CollisionPdu -Sent DIS PDU 5 DISPDUType: SERVICE_REQUEST: 5 of type edu.nps.moves.dis7.ServiceRequestPdu -Sent DIS PDU 6 DISPDUType: RESUPPLY_OFFER: 6 of type edu.nps.moves.dis7.ResupplyOfferPdu -Sent DIS PDU 7 DISPDUType: RESUPPLY_RECEIVED: 7 of type edu.nps.moves.dis7.ResupplyReceivedPdu -Sent DIS PDU 8 DISPDUType: RESUPPLY_CANCEL: 8 of type edu.nps.moves.dis7.ResupplyCancelPdu -Sent DIS PDU 9 DISPDUType: REPAIR_COMPLETE: 9 of type edu.nps.moves.dis7.RepairCompletePdu -Sent DIS PDU 10 DISPDUType: REPAIR_RESPONSE: 10 of type edu.nps.moves.dis7.RepairResponsePdu -Sent DIS PDU 11 DISPDUType: CREATE_ENTITY: 11 of type edu.nps.moves.dis7.CreateEntityPdu -Sent DIS PDU 12 DISPDUType: REMOVE_ENTITY: 12 of type edu.nps.moves.dis7.RemoveEntityPdu -Sent DIS PDU 13 DISPDUType: START_RESUME: 13 of type edu.nps.moves.dis7.StartResumePdu -Sent DIS PDU 14 DISPDUType: STOP_FREEZE: 14 of type edu.nps.moves.dis7.StopFreezePdu -Sent DIS PDU 15 DISPDUType: ACKNOWLEDGE: 15 of type edu.nps.moves.dis7.AcknowledgePdu -Sent DIS PDU 16 DISPDUType: ACTION_REQUEST: 16 of type edu.nps.moves.dis7.ActionRequestPdu -Sent DIS PDU 17 DISPDUType: ACTION_RESPONSE: 17 of type edu.nps.moves.dis7.ActionResponsePdu -Sent DIS PDU 18 DISPDUType: DATA_QUERY: 18 of type edu.nps.moves.dis7.DataQueryPdu -Sent DIS PDU 19 DISPDUType: SET_DATA: 19 of type edu.nps.moves.dis7.SetDataPdu -Sent DIS PDU 20 DISPDUType: DATA: 20 of type edu.nps.moves.dis7.DataPdu -Sent DIS PDU 21 DISPDUType: EVENT_REPORT: 21 of type edu.nps.moves.dis7.EventReportPdu -Sent DIS PDU 22 DISPDUType: COMMENT: 22 of type edu.nps.moves.dis7.CommentPdu -Sent DIS PDU 23 DISPDUType: ELECTROMAGNETIC_EMISSION: 23 of type edu.nps.moves.dis7.ElectromagneticEmissionPdu -Sent DIS PDU 24 DISPDUType: DESIGNATOR: 24 of type edu.nps.moves.dis7.DesignatorPdu -Sent DIS PDU 25 DISPDUType: TRANSMITTER: 25 of type edu.nps.moves.dis7.TransmitterPdu -Sent DIS PDU 26 DISPDUType: SIGNAL: 26 of type edu.nps.moves.dis7.SignalPdu -Sent DIS PDU 27 DISPDUType: RECEIVER: 27 of type edu.nps.moves.dis7.ReceiverPdu -Sent DIS PDU 28 DISPDUType: IDENTIFICATION_FRIEND_OR_FOE: 28 of type edu.nps.moves.dis7.IdentificationFriendOrFoePdu -Sent DIS PDU 29 DISPDUType: UNDERWATER_ACOUSTIC: 29 of type edu.nps.moves.dis7.UnderwaterAcousticPdu -Sent DIS PDU 30 DISPDUType: SUPPLEMENTAL_EMISSION_ENTITY_STATE: 30 of type edu.nps.moves.dis7.SupplementalEmissionEntityStatePdu -Sent DIS PDU 31 DISPDUType: INTERCOM_SIGNAL: 31 of type edu.nps.moves.dis7.IntercomSignalPdu -Sent DIS PDU 32 DISPDUType: INTERCOM_CONTROL: 32 of type edu.nps.moves.dis7.IntercomControlPdu -Sent DIS PDU 33 DISPDUType: AGGREGATE_STATE: 33 of type edu.nps.moves.dis7.AggregateStatePdu -Sent DIS PDU 34 DISPDUType: ISGROUPOF: 34 of type edu.nps.moves.dis7.IsGroupOfPdu -Sent DIS PDU 35 DISPDUType: TRANSFER_OWNERSHIP: 35 of type edu.nps.moves.dis7.TransferOwnershipPdu -Sent DIS PDU 36 DISPDUType: ISPARTOF: 36 of type edu.nps.moves.dis7.IsPartOfPdu -Sent DIS PDU 37 DISPDUType: MINEFIELD_STATE: 37 of type edu.nps.moves.dis7.MinefieldStatePdu -Sent DIS PDU 38 DISPDUType: MINEFIELD_QUERY: 38 of type edu.nps.moves.dis7.MinefieldQueryPdu -Sent DIS PDU 39 DISPDUType: MINEFIELD_DATA: 39 of type edu.nps.moves.dis7.MinefieldDataPdu -Sent DIS PDU 40 DISPDUType: MINEFIELD_RESPONSE_NACK: 40 of type edu.nps.moves.dis7.MinefieldResponseNACKPdu -Sent DIS PDU 41 DISPDUType: ENVIRONMENTAL_PROCESS: 41 of type edu.nps.moves.dis7.EnvironmentalProcessPdu -Sent DIS PDU 42 DISPDUType: GRIDDED_DATA: 42 of type edu.nps.moves.dis7.GriddedDataPdu -Sent DIS PDU 43 DISPDUType: POINT_OBJECT_STATE: 43 of type edu.nps.moves.dis7.PointObjectStatePdu -Sent DIS PDU 44 DISPDUType: LINEAR_OBJECT_STATE: 44 of type edu.nps.moves.dis7.LinearObjectStatePdu -Sent DIS PDU 45 DISPDUType: AREAL_OBJECT_STATE: 45 of type edu.nps.moves.dis7.ArealObjectStatePdu -Sent DIS PDU 46 DISPDUType: TIME_SPACE_POSITION_INFORMATION: 46 of type edu.nps.moves.dis7.TimeSpacePositionInformationPdu -Sent DIS PDU 47 DISPDUType: APPEARANCE: 47 of type edu.nps.moves.dis7.AppearancePdu -Sent DIS PDU 48 DISPDUType: ARTICULATED_PARTS: 48 of type edu.nps.moves.dis7.ArticulatedPartsPdu -Sent DIS PDU 49 DISPDUType: LIVE_ENTITY_FIRE: 49 of type edu.nps.moves.dis7.LiveEntityFirePdu -Sent DIS PDU 50 DISPDUType: LIVE_ENTITY_DETONATION: 50 of type edu.nps.moves.dis7.LiveEntityDetonationPdu -Sent DIS PDU 51 DISPDUType: CREATE_ENTITY_RELIABLE: 51 of type edu.nps.moves.dis7.CreateEntityReliablePdu -Sent DIS PDU 52 DISPDUType: REMOVE_ENTITY_RELIABLE: 52 of type edu.nps.moves.dis7.RemoveEntityReliablePdu -Sent DIS PDU 53 DISPDUType: START_RESUME_RELIABLE: 53 of type edu.nps.moves.dis7.StartResumeReliablePdu -Sent DIS PDU 54 DISPDUType: STOP_FREEZE_RELIABLE: 54 of type edu.nps.moves.dis7.StopFreezeReliablePdu -Sent DIS PDU 55 DISPDUType: ACKNOWLEDGE_RELIABLE: 55 of type edu.nps.moves.dis7.AcknowledgeReliablePdu -Sent DIS PDU 56 DISPDUType: ACTION_REQUEST_RELIABLE: 56 of type edu.nps.moves.dis7.ActionRequestReliablePdu -Sent DIS PDU 57 DISPDUType: ACTION_RESPONSE_RELIABLE: 57 of type edu.nps.moves.dis7.ActionResponseReliablePdu -Sent DIS PDU 58 DISPDUType: DATA_QUERY_RELIABLE: 58 of type edu.nps.moves.dis7.DataQueryReliablePdu -Sent DIS PDU 59 DISPDUType: SET_DATA_RELIABLE: 59 of type edu.nps.moves.dis7.SetDataReliablePdu -Sent DIS PDU 60 DISPDUType: DATA_RELIABLE: 60 of type edu.nps.moves.dis7.DataReliablePdu -Sent DIS PDU 61 DISPDUType: EVENT_REPORT_RELIABLE: 61 of type edu.nps.moves.dis7.EventReportReliablePdu -Sent DIS PDU 62 DISPDUType: COMMENT_RELIABLE: 62 of type edu.nps.moves.dis7.CommentReliablePdu -Sent DIS PDU 63 DISPDUType: RECORD_RELIABLE: 63 of type edu.nps.moves.dis7.RecordReliablePdu -Sent DIS PDU 64 DISPDUType: SET_RECORD_RELIABLE: 64 of type edu.nps.moves.dis7.SetRecordReliablePdu -Sent DIS PDU 65 DISPDUType: RECORD_QUERY_RELIABLE: 65 of type edu.nps.moves.dis7.RecordQueryReliablePdu -Sent DIS PDU 66 DISPDUType: COLLISION_ELASTIC: 66 of type edu.nps.moves.dis7.CollisionElasticPdu -Sent DIS PDU 67 DISPDUType: ENTITY_STATE_UPDATE: 67 of type edu.nps.moves.dis7.EntityStateUpdatePdu -Sent DIS PDU 68 DISPDUType: DIRECTED_ENERGY_FIRE: 68 of type edu.nps.moves.dis7.DirectedEnergyFirePdu -Sent DIS PDU 69 DISPDUType: ENTITY_DAMAGE_STATUS: 69 of type edu.nps.moves.dis7.EntityDamageStatusPdu -Sent DIS PDU 70 DISPDUType: INFORMATION_OPERATIONS_ACTION: 70 of type edu.nps.moves.dis7.InformationOperationsActionPdu -Sent DIS PDU 71 DISPDUType: INFORMATION_OPERATIONS_REPORT: 71 of type edu.nps.moves.dis7.InformationOperationsReportPdu -Sent DIS PDU 72 DISPDUType: ATTRIBUTE: 72 of type edu.nps.moves.dis7.AttributePdu -DisExamplesOpenDis7.AllPduSender complete, sent 72 PDUs total. -BUILD SUCCESSFUL (total time: 2 seconds) +Sent DIS PDU 1 DISPDUType: 1 ENTITY_STATE of type edu.nps.moves.dis7.EntityStatePdu +Sent DIS PDU 2 DISPDUType: 2 FIRE of type edu.nps.moves.dis7.FirePdu +Sent DIS PDU 3 DISPDUType: 3 DETONATION of type edu.nps.moves.dis7.DetonationPdu +Sent DIS PDU 4 DISPDUType: 4 COLLISION of type edu.nps.moves.dis7.CollisionPdu +Sent DIS PDU 5 DISPDUType: 5 SERVICE_REQUEST of type edu.nps.moves.dis7.ServiceRequestPdu +Sent DIS PDU 6 DISPDUType: 6 RESUPPLY_OFFER of type edu.nps.moves.dis7.ResupplyOfferPdu +Sent DIS PDU 7 DISPDUType: 7 RESUPPLY_RECEIVED of type edu.nps.moves.dis7.ResupplyReceivedPdu +Sent DIS PDU 8 DISPDUType: 8 RESUPPLY_CANCEL of type edu.nps.moves.dis7.ResupplyCancelPdu +Sent DIS PDU 9 DISPDUType: 9 REPAIR_COMPLETE of type edu.nps.moves.dis7.RepairCompletePdu +Sent DIS PDU 10 DISPDUType: 10 REPAIR_RESPONSE of type edu.nps.moves.dis7.RepairResponsePdu +Sent DIS PDU 11 DISPDUType: 11 CREATE_ENTITY of type edu.nps.moves.dis7.CreateEntityPdu +Sent DIS PDU 12 DISPDUType: 12 REMOVE_ENTITY of type edu.nps.moves.dis7.RemoveEntityPdu +Sent DIS PDU 13 DISPDUType: 13 START_RESUME of type edu.nps.moves.dis7.StartResumePdu +Sent DIS PDU 14 DISPDUType: 14 STOP_FREEZE of type edu.nps.moves.dis7.StopFreezePdu +Sent DIS PDU 15 DISPDUType: 15 ACKNOWLEDGE of type edu.nps.moves.dis7.AcknowledgePdu +Sent DIS PDU 16 DISPDUType: 16 ACTION_REQUEST of type edu.nps.moves.dis7.ActionRequestPdu +Sent DIS PDU 17 DISPDUType: 17 ACTION_RESPONSE of type edu.nps.moves.dis7.ActionResponsePdu +Sent DIS PDU 18 DISPDUType: 18 DATA_QUERY of type edu.nps.moves.dis7.DataQueryPdu +Sent DIS PDU 19 DISPDUType: 19 SET_DATA of type edu.nps.moves.dis7.SetDataPdu +Sent DIS PDU 20 DISPDUType: 20 DATA of type edu.nps.moves.dis7.DataPdu +Sent DIS PDU 21 DISPDUType: 21 EVENT_REPORT of type edu.nps.moves.dis7.EventReportPdu +Sent DIS PDU 22 DISPDUType: 22 COMMENT of type edu.nps.moves.dis7.CommentPdu +Sent DIS PDU 23 DISPDUType: 23 ELECTROMAGNETIC_EMISSION of type edu.nps.moves.dis7.ElectromagneticEmissionPdu +Sent DIS PDU 24 DISPDUType: 24 DESIGNATOR of type edu.nps.moves.dis7.DesignatorPdu +Sent DIS PDU 25 DISPDUType: 25 TRANSMITTER of type edu.nps.moves.dis7.TransmitterPdu +Sent DIS PDU 26 DISPDUType: 26 SIGNAL of type edu.nps.moves.dis7.SignalPdu +Sent DIS PDU 27 DISPDUType: 27 RECEIVER of type edu.nps.moves.dis7.ReceiverPdu +Sent DIS PDU 28 DISPDUType: 28 IDENTIFICATION_FRIEND_OR_FOE of type edu.nps.moves.dis7.IdentificationFriendOrFoePdu +Sent DIS PDU 29 DISPDUType: 29 UNDERWATER_ACOUSTIC of type edu.nps.moves.dis7.UnderwaterAcousticPdu +Sent DIS PDU 30 DISPDUType: 30 SUPPLEMENTAL_EMISSION_ENTITY_STATE of type edu.nps.moves.dis7.SupplementalEmissionEntityStatePdu +Sent DIS PDU 31 DISPDUType: 31 INTERCOM_SIGNAL of type edu.nps.moves.dis7.IntercomSignalPdu +Sent DIS PDU 32 DISPDUType: 32 INTERCOM_CONTROL of type edu.nps.moves.dis7.IntercomControlPdu +Sent DIS PDU 33 DISPDUType: 33 AGGREGATE_STATE of type edu.nps.moves.dis7.AggregateStatePdu +Sent DIS PDU 34 DISPDUType: 34 ISGROUPOF of type edu.nps.moves.dis7.IsGroupOfPdu +Sent DIS PDU 35 DISPDUType: 35 TRANSFER_OWNERSHIP of type edu.nps.moves.dis7.TransferOwnershipPdu +Sent DIS PDU 36 DISPDUType: 36 ISPARTOF of type edu.nps.moves.dis7.IsPartOfPdu +Sent DIS PDU 37 DISPDUType: 37 MINEFIELD_STATE of type edu.nps.moves.dis7.MinefieldStatePdu +Sent DIS PDU 38 DISPDUType: 38 MINEFIELD_QUERY of type edu.nps.moves.dis7.MinefieldQueryPdu +Sent DIS PDU 39 DISPDUType: 39 MINEFIELD_DATA of type edu.nps.moves.dis7.MinefieldDataPdu +Sent DIS PDU 40 DISPDUType: 40 MINEFIELD_RESPONSE_NACK of type edu.nps.moves.dis7.MinefieldResponseNACKPdu +Sent DIS PDU 41 DISPDUType: 41 ENVIRONMENTAL_PROCESS of type edu.nps.moves.dis7.EnvironmentalProcessPdu +Sent DIS PDU 42 DISPDUType: 42 GRIDDED_DATA of type edu.nps.moves.dis7.GriddedDataPdu +Sent DIS PDU 43 DISPDUType: 43 POINT_OBJECT_STATE of type edu.nps.moves.dis7.PointObjectStatePdu +Sent DIS PDU 44 DISPDUType: 44 LINEAR_OBJECT_STATE of type edu.nps.moves.dis7.LinearObjectStatePdu +Sent DIS PDU 45 DISPDUType: 45 AREAL_OBJECT_STATE of type edu.nps.moves.dis7.ArealObjectStatePdu +Sent DIS PDU 46 DISPDUType: 46 TIME_SPACE_POSITION_INFORMATION of type edu.nps.moves.dis7.TimeSpacePositionInformationPdu +Sent DIS PDU 47 DISPDUType: 47 APPEARANCE of type edu.nps.moves.dis7.AppearancePdu +Sent DIS PDU 48 DISPDUType: 48 ARTICULATED_PARTS of type edu.nps.moves.dis7.ArticulatedPartsPdu +Sent DIS PDU 49 DISPDUType: 49 LIVE_ENTITY_FIRE of type edu.nps.moves.dis7.LiveEntityFirePdu +Sent DIS PDU 50 DISPDUType: 50 LIVE_ENTITY_DETONATION of type edu.nps.moves.dis7.LiveEntityDetonationPdu +Sent DIS PDU 51 DISPDUType: 51 CREATE_ENTITY_RELIABLE of type edu.nps.moves.dis7.CreateEntityReliablePdu +Sent DIS PDU 52 DISPDUType: 52 REMOVE_ENTITY_RELIABLE of type edu.nps.moves.dis7.RemoveEntityReliablePdu +Sent DIS PDU 53 DISPDUType: 53 START_RESUME_RELIABLE of type edu.nps.moves.dis7.StartResumeReliablePdu +Sent DIS PDU 54 DISPDUType: 54 STOP_FREEZE_RELIABLE of type edu.nps.moves.dis7.StopFreezeReliablePdu +Sent DIS PDU 55 DISPDUType: 55 ACKNOWLEDGE_RELIABLE of type edu.nps.moves.dis7.AcknowledgeReliablePdu +Sent DIS PDU 56 DISPDUType: 56 ACTION_REQUEST_RELIABLE of type edu.nps.moves.dis7.ActionRequestReliablePdu +Sent DIS PDU 57 DISPDUType: 57 ACTION_RESPONSE_RELIABLE of type edu.nps.moves.dis7.ActionResponseReliablePdu +Sent DIS PDU 58 DISPDUType: 58 DATA_QUERY_RELIABLE of type edu.nps.moves.dis7.DataQueryReliablePdu +Sent DIS PDU 59 DISPDUType: 59 SET_DATA_RELIABLE of type edu.nps.moves.dis7.SetDataReliablePdu +Sent DIS PDU 60 DISPDUType: 60 DATA_RELIABLE of type edu.nps.moves.dis7.DataReliablePdu +Sent DIS PDU 61 DISPDUType: 61 EVENT_REPORT_RELIABLE of type edu.nps.moves.dis7.EventReportReliablePdu +Sent DIS PDU 62 DISPDUType: 62 COMMENT_RELIABLE of type edu.nps.moves.dis7.CommentReliablePdu +Sent DIS PDU 63 DISPDUType: 63 RECORD_RELIABLE of type edu.nps.moves.dis7.RecordReliablePdu +Sent DIS PDU 64 DISPDUType: 64 SET_RECORD_RELIABLE of type edu.nps.moves.dis7.SetRecordReliablePdu +Sent DIS PDU 65 DISPDUType: 65 RECORD_QUERY_RELIABLE of type edu.nps.moves.dis7.RecordQueryReliablePdu +Sent DIS PDU 66 DISPDUType: 66 COLLISION_ELASTIC of type edu.nps.moves.dis7.CollisionElasticPdu +Sent DIS PDU 67 DISPDUType: 67 ENTITY_STATE_UPDATE of type edu.nps.moves.dis7.EntityStateUpdatePdu +Sent DIS PDU 68 DISPDUType: 68 DIRECTED_ENERGY_FIRE of type edu.nps.moves.dis7.DirectedEnergyFirePdu +Sent DIS PDU 69 DISPDUType: 69 ENTITY_DAMAGE_STATUS of type edu.nps.moves.dis7.EntityDamageStatusPdu +Sent DIS PDU 70 DISPDUType: 70 INFORMATION_OPERATIONS_ACTION of type edu.nps.moves.dis7.InformationOperationsActionPdu +Sent DIS PDU 71 DISPDUType: 71 INFORMATION_OPERATIONS_REPORT of type edu.nps.moves.dis7.InformationOperationsReportPdu +Sent DIS PDU 72 DISPDUType: 72 ATTRIBUTE of type edu.nps.moves.dis7.AttributePdu +OpenDis7Examples.AllPduSender complete, sent 72 PDUs total. +BUILD SUCCESSFUL (total time: 4 seconds) diff --git a/examples/src/OpenDis7Examples/EspduReceiver.java b/examples/src/OpenDis7Examples/EspduReceiver.java index 81eb4183d1f63d9b5bd8a7c51ed60de94d807e6f..560adf8d65f28a8430f2023201033a6a7415a082 100755 --- a/examples/src/OpenDis7Examples/EspduReceiver.java +++ b/examples/src/OpenDis7Examples/EspduReceiver.java @@ -4,7 +4,7 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.*; /** @@ -26,15 +26,21 @@ public class EspduReceiver /** Default multicast port used, matches Wireshark DIS capture default */ public static final int DEFAULT_MULTICAST_PORT = EspduSender.DEFAULT_MULTICAST_PORT; + + /** + * Output prefix to identify this class + */ + private final static String TRACE_PREFIX = "[" + EspduReceiver.class.getName() + "] "; public static void main(String args[]) { - System.out.println("DisExamplesOpenDis7.EspduReceiver started..."); + System.out.println(TRACE_PREFIX + "started..."); MulticastSocket socket; - DatagramPacket packet; - InetAddress address; - PduFactory pduFactory = new PduFactory(); + DatagramPacket packet; + InetAddress address; + PduFactory pduFactory = new PduFactory(); + int pduCount = 0; try { // Specify the socket to receive data @@ -42,8 +48,11 @@ public class EspduReceiver // socket.setBroadcast(true); address = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); - socket.joinGroup(address); - +////// socket.joinGroup(address); // TODO not needed! + + System.out.println(TRACE_PREFIX + "listening for PDU packets on " + address.getHostAddress() + " port " + DEFAULT_MULTICAST_PORT); + System.out.println("==============="); + while (true) // Loop infinitely, receiving datagrams { byte buffer[] = new byte[MAX_PDU_SIZE]; @@ -56,36 +65,38 @@ public class EspduReceiver System.out.println("Bundle size is " + pduBundle.size()); // end iterator loop through PDU bundle - for (Pdu aPdu : pduBundle) { - String receiptMessage = "received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName(); + for (Pdu aPdu : pduBundle) + { + pduCount++; + String receiptMessage = String.format("%3s", pduCount) // right justify, 3 characters + + ". received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName(); if (aPdu instanceof EntityStatePdu) { - System.out.println("==============="); System.out.println(receiptMessage); EntityID entityID = ((EntityStatePdu)aPdu).getEntityID(); Vector3Double position = ((EntityStatePdu)aPdu).getEntityLocation(); - System.out.println(" entityID triplet: [" + entityID.getSiteID()+ ", " + entityID.getApplicationID()+ ", " + entityID.getEntityID()+ "] "); - System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + System.out.println(" entityID triplet: [" + entityID.getSiteID()+ ", " + entityID.getApplicationID()+ ", " + entityID.getEntityID()+ "] "); + System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); } else if (aPdu instanceof FirePdu) { System.out.println(receiptMessage); Vector3Double position = ((FirePdu)aPdu).getLocationInWorldCoordinates(); - System.out.println(" FirePdu locationInWorldCoordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); - + System.out.println(" FirePdu locationInWorldCoordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); + System.out.println("==============="); } else { System.out.println(receiptMessage); } - } - } // end while + } // end of bundle loop + } // end of while loop } // end try block - catch (IOException e) + catch (IOException ioe) { - System.out.println("Problem with DisExamplesOpenDis7.EspduReceiver, see exception trace:"); - System.out.println(e); + System.out.println(TRACE_PREFIX + "Problem with input/output, see exception trace:"); + System.out.println(ioe); } - System.out.println("DisExamplesOpenDis7.EspduReceiver complete."); + System.out.println(TRACE_PREFIX + "complete."); } // end main } // end class diff --git a/examples/src/OpenDis7Examples/EspduSender.java b/examples/src/OpenDis7Examples/EspduSender.java index 2933e2da02151db7b0064163a00def6b3606eda1..28178a9d36f4bdf962a9da4f0a742cd465fbc635 100644 --- a/examples/src/OpenDis7Examples/EspduSender.java +++ b/examples/src/OpenDis7Examples/EspduSender.java @@ -4,11 +4,12 @@ import java.io.*; import java.net.*; import java.util.*; -import edu.nps.moves.dis7.*; +import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.enumerations.Country; import edu.nps.moves.dis7.enumerations.EntityKind; import edu.nps.moves.dis7.enumerations.PlatformDomain; import edu.nps.moves.dis7.utilities.*; +import edu.nps.moves.dis7.entities.usa.platform.land.M1A2; /** * Creates and sends ESPDUs in IEEE binary format. Adapted from OpenDIS library @@ -22,7 +23,7 @@ public class EspduSender /** * Putting any upper limit on # packets sent avoids possibility of non-terminating infinite loops that continue sending packets. */ - public static final int NUMBER_PDUS_TO_SEND = 5; // 5000 + public static final int NUMBER_OF_LOOPS = 1; // 5 /** * Default multicast group address we send on. @@ -32,11 +33,16 @@ public class EspduSender /** * Default multicast port used, matches Wireshark DIS capture default */ - public static final int DEFAULT_MULTICAST_PORT = 3000; - + public static final int DEFAULT_MULTICAST_PORT = 3000; + public enum NetworkMode { UNICAST, MULTICAST, BROADCAST }; + + /** + * Output prefix to identify this class, helps with logging + */ + private final static String TRACE_PREFIX = "[" + EspduSender.class.getName() + "] "; /** * Possible system properties, passed in via -Dattr=val networkMode: @@ -52,16 +58,16 @@ public class EspduSender @SuppressWarnings("SleepWhileInLoop") // allows Thread.sleep(value) without warning in code public static void main(String args[]) { - System.out.println("DisExamplesOpenDis7.EspduSender started..."); + System.out.println(TRACE_PREFIX + " started..."); - // Default settings. These are used if no system properties are set. - // If system properties are passed in, these are overridden later. - NetworkMode networkMode = NetworkMode.BROADCAST; - InetAddress address = null; // must be initialized, even if null - int port = DEFAULT_MULTICAST_PORT; - MulticastSocket socket = null; // must be initialized to avoid later error, even if null; - EntityStatePdu espdu = new EntityStatePdu(); - DisTime disTime = new DisTime(); + // Default settings. These are used if no system properties are set. + // If system properties are passed in, these are overridden later. + NetworkMode networkMode = NetworkMode.MULTICAST; + InetAddress address = null; // must be initialized, even if null + int port = DEFAULT_MULTICAST_PORT; + MulticastSocket socket = null; // must be initialized to avoid later error, even if null; + EntityStatePdu espdu = new EntityStatePdu(); + DisTime disTime = new DisTime(); // ICBM coordinates for my office double latitude = 36.595517; @@ -72,7 +78,7 @@ public class EspduSender } catch (UnknownHostException e) { - System.out.println(e + " Cannot create multicast address"); + System.out.println(TRACE_PREFIX + e + " Cannot create multicast address"); System.exit(0); } @@ -121,16 +127,30 @@ public class EspduSender { throw new RuntimeException("*** Error: sending to multicast address, but destination address " + address.toString() + "is not multicast"); } - socket.joinGroup(address); + socket.joinGroup(address); // TODO select correct NetworkInterface } } // end networkModeString + else if (networkMode == NetworkMode.MULTICAST) + { + networkModeString = "multicast"; + } + else if (networkMode == NetworkMode.UNICAST) + { + networkModeString = "unicast"; + } + else if (networkMode == NetworkMode.BROADCAST) + { + networkModeString = "broadcast"; + } } catch (IOException | RuntimeException e) { - System.out.println("Unable to initialize network correctly, exiting."); + System.out.println(TRACE_PREFIX + "Unable to initialize network correctly, exiting."); System.out.println(e); System.exit(-1); // outta here } + System.out.println(TRACE_PREFIX + " sending " + networkModeString + " ESPDU packets to " + + address.getHostAddress() + " port " + port); // Initialize values in the Entity State PDU object. The exercise ID is // a way to differentiate between different virtual worlds on one network. @@ -147,7 +167,7 @@ public class EspduSender entityID.setSiteID ((short)1); // TODO utility method to allow int values entityID.setApplicationID((short)2); entityID.setEntityID ((short)3); - espdu.setEntityID(entityID); + espdu.setEntityID(entityID); // TODO utility method to allow setting all three at once // Set the entity type. SISO has a big list of enumerations, so that by // specifying various numbers we can say this is an M1A2 American tank, @@ -156,27 +176,39 @@ public class EspduSender // enumerations in C++ and Java, but to keep things simple we just use // numbers here. + // Manual way to override platform information: + EntityType entityType = espdu.getEntityType() + .setEntityKind (EntityKind.PLATFORM).setEntityKind (EntityKind.PLATFORM) //(short) 1); // Platform (vs lifeform, munition, sensor, etc.); //(short) 1); // Platform (vs lifeform, munition, sensor, etc.) + .setCountry (Country.UNITED_STATES_OF_AMERICA_USA) // 225 USA + .setDomain (Domain.inst(PlatformDomain.LAND)) // Land (vs air, surface, subsurface, space) + .setCategory ((byte) 1) // Tank + .setSubCategory((byte) 1) // M1 Abrams + .setSpecific ((byte) 3); // M1A2 Abrams + // New way using entity jar(s) espdu.setEntityType(new edu.nps.moves.dis7.entities.usa.platform.land.M1A2()); - - // Manual way: - /* - */ - EntityType entityType = espdu.getEntityType(); - entityType.setEntityKind(EntityKind.PLATFORM); //(short) 1); // Platform (vs lifeform, munition, sensor, etc.) - entityType.setCountry(Country.UNITED_STATES_OF_AMERICA_USA); // 225 USA - entityType.setDomain(Domain.inst(PlatformDomain.LAND)); // Land (vs air, surface, subsurface, space) - entityType.setCategory ((byte) 1); // Tank - entityType.setSubCategory((byte) 1); // M1 Abrams - entityType.setSpecific ((byte) 3); // M1A2 Abrams + // or simply use an enumeration by name, with accompanying import statement above + espdu.setEntityType(new M1A2()); - Set<InetAddress> broadcastAddresses; + // Inspecting an enumeration + System.out.println("==============="); + System.out.println("espdu entityType information:"); + System.out.println(" EntityKind =" + espdu.getEntityType().getEntityKind()); + System.out.println(" Country =" + espdu.getEntityType().getCountry()); + System.out.println(" Domain =" + espdu.getEntityType().getDomain()); + System.out.println(" Category =" + espdu.getEntityType().getCategory()); + System.out.println(" SubCategory=" + espdu.getEntityType().getSubCategory()); + System.out.println(" Specific =" + espdu.getEntityType().getCountry()); + // TODO round trip lookup + + Set<InetAddress> localNetworkAddresses; try // Loop through sending N ESPDUs { - System.out.println("Sending " + NUMBER_PDUS_TO_SEND + " sets of packets:"); // + address.toString() + System.out.println(TRACE_PREFIX + "sending " + NUMBER_OF_LOOPS + " sets of packets:"); // + address.toString() - for (int index = 0; index < NUMBER_PDUS_TO_SEND; index++) { + for (int index = 0; index < NUMBER_OF_LOOPS; index++) + { // DIS time is a pain in the uh, neck. DIS time units are 2^31-1 units per // hour, and time is set to DIS time units from the top of the hour. // This means that if you start sending just before the top of the hour @@ -264,33 +296,64 @@ public class EspduSender firePdu.setLocationInWorldCoordinates(espdu.getEntityLocation()); byte[] fireArray = firePdu.marshal(); - broadcastAddresses = getBroadcastAddresses(); - for (InetAddress broadcast : broadcastAddresses) { - if (espduArray.length > 0) - { - System.out.println("Sending espdu datagram packet to " + broadcast); - packet = new DatagramPacket(espduArray, espduArray.length, broadcast, port); - socket.send(packet); - } - // TODO experiment with these! 8) - if (fireArray.length > 0) - { - System.out.println("Sending fire datagram packet to " + broadcast); - packet = new DatagramPacket(fireArray, fireArray.length, broadcast, port); // alternate - socket.send(packet); - } } - +// CommentPdu newCommentPdu = new CommentPdu(); +// ArrayList<VariableDatum> payloadList = new ArrayList<>(); +// ArrayList<String> commentsList = new ArrayList<>(); +// commentsList.add("Hello CommentPDU"); +// commentsList.add("Here is a second line of text in this comment."); +// if (!commentsList.isEmpty()) +// System.out.println("Preparing CommentPDU:"); +// +// for (String comment : commentsList) +// { +// VariableDatum newVariableDatum = new VariableDatum(); +// newVariableDatum.setVariableDatumValue (comment.getBytes()); // conversion +// newVariableDatum.setVariableDatumLengthInBytes(comment.getBytes().length); // also available in bits, see spec and javadoc +// // alternatively, you do not need to set this and the marshaller will figure it out from the byte array +// // (see javadoc for VariableDatum.setVariableDatumLength()) +// payloadList.add(newVariableDatum); +// System.out.println(" \"" + comment + "\""); +// } +// newCommentPdu.setVariableDatums(payloadList); +// byte[] commentArray = newCommentPdu.marshal(); + + localNetworkAddresses = getBroadcastAddresses(); + for (InetAddress networkAddress : localNetworkAddresses) { + if (espduArray.length > 0) + { + System.out.println(TRACE_PREFIX + "sending datagram packet [" + espdu.getPduType().toString() + "] to " + + String.format("%-15s", networkAddress.getHostAddress()) + " port " + port); + packet = new DatagramPacket(espduArray, espduArray.length, networkAddress, port); + socket.send(packet); + } + // TODO experiment with these! 8) + if (fireArray.length > 0) + { + System.out.println(TRACE_PREFIX + "sending datagram packet [" + firePdu.getPduType().toString() + " ] to " + + String.format("%-15s", networkAddress.getHostAddress()) + " port " + port); + packet = new DatagramPacket(fireArray, fireArray.length, networkAddress, port); // alternate + socket.send(packet); + } +// // TODO experiment with these! 8) +// if (newCommentPdu != null) +// { +// System.out.println(TRACE_PREFIX + "sending datagram packet [" + newCommentPdu.getPduType().toString() + " ] to " + +// String.format("%-15s", networkAddress.getHostAddress()) + " port " + port); +// packet = new DatagramPacket(commentArray, commentArray.length, networkAddress, port); // alternate +// socket.send(packet); +// } + } // Send every 1 second within loop. Otherwise all this will be all over in a fraction of a second. Thread.sleep(1000); // msec } } catch (Exception e) { - System.out.println("Problem with DisExamplesOpenDis7.EspduSender, see exception trace:"); + System.out.println(TRACE_PREFIX + "Problem with " + e + ", see exception trace:"); System.out.println(e); } System.out.println("==============="); - System.out.println("DisExamplesOpenDis7.EspduSender complete."); + System.out.println(TRACE_PREFIX + "complete."); } /** @@ -319,25 +382,25 @@ public class EspduSender if (anInterface.isUp()) { - for (InterfaceAddress anAddress : anInterface.getInterfaceAddresses()) { - if ((anAddress == null || anAddress.getAddress().isLinkLocalAddress())) - { - continue; - } - - //System.out.println("Getting broadcast address for " + anAddress); - InetAddress broadcastAddress = anAddress.getBroadcast(); - if (broadcastAddress != null) - { - broadcastAddresses.add(broadcastAddress); - } - } + for (InterfaceAddress anAddress : anInterface.getInterfaceAddresses()) { + if ((anAddress == null || anAddress.getAddress().isLinkLocalAddress())) + { + continue; + } + + //System.out.println("Getting broadcast address for " + anAddress); + InetAddress broadcastAddress = anAddress.getBroadcast(); + if (broadcastAddress != null) + { + broadcastAddresses.add(broadcastAddress); + } + } } } } catch (SocketException e) { - System.out.println("Problem with DisExamplesOpenDis7.EspduSender.getBroadcastAddresses(), see exception trace:"); + System.out.println(TRACE_PREFIX + "Problem with .getBroadcastAddresses(), see exception trace:" + e); System.out.println(e); } return broadcastAddresses; diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgram.java b/examples/src/OpenDis7Examples/ExampleSimulationProgram.java new file mode 100644 index 0000000000000000000000000000000000000000..19263d3685b695a5b6d5f3bfd4623f74fb06543b --- /dev/null +++ b/examples/src/OpenDis7Examples/ExampleSimulationProgram.java @@ -0,0 +1,288 @@ +/** + * Copyright (c) 2008-2020, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved. + * This work is provided under a BSD open-source license, see project license.html and license.txt + */ +package OpenDis7Examples; + +import edu.nps.moves.dis7.enumerations.VariableRecordType; +import edu.nps.moves.dis7.pdus.CommentPdu; +import edu.nps.moves.dis7.pdus.EntityID; +import edu.nps.moves.dis7.pdus.EntityStatePdu; +import edu.nps.moves.dis7.pdus.FirePdu; +import edu.nps.moves.dis7.pdus.Pdu; +import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface; +import edu.nps.moves.dis7.utilities.PduFactory; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ExampleSimulationProgram +{ + // class variables + PduFactory pduFactory = new PduFactory(); + DisThreadedNetworkInterface disNetworkInterface; + DisThreadedNetworkInterface.PduListener pduListener; + Pdu receivedPdu; + + private String networkAddress = "239.1.2.3"; + private int networkPort = 3000; + + /** + * Constructor design goal: additional built-in initialization conveniences can go here + * to keep student efforts focused on the runSimulation() method. + */ + public ExampleSimulationProgram() + { + // Under consideration. Constructor is not currently needed. + } + + /** + * Utility Constructor + * @param address network address to use + * @param port corresponding network port to use + */ + public ExampleSimulationProgram(String address, int port) + { + setNetworkAddress(address); + + setNetworkPort(port); + } + + /** + * @return the networkAddress + */ + public String getNetworkAddress() + { + return networkAddress; + } + + /** + * @param networkAddress the networkAddress to set + */ + public final void setNetworkAddress(String networkAddress) + { + this.networkAddress = networkAddress; + } + + /** + * @return the networkPort + */ + public int getNetworkPort() + { + return networkPort; + } + + /** + * @param networkPort the networkPort to set + */ + public final void setNetworkPort(int networkPort) + { + this.networkPort = networkPort; + } + + /** + * Initialize network interface, choosing best available network interface + */ + public void setUpNetworkInterface() + { + disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort()); + + System.out.println("Network confirmation: address=" + disNetworkInterface.getMcastGroup() + " port=" + disNetworkInterface.getDisPort()); + pduListener = new DisThreadedNetworkInterface.PduListener() + { + /** Callback handler for listener */ + @Override + public void incomingPdu(Pdu newPdu) + { + receivedPdu = newPdu; + } + }; + disNetworkInterface.addListener(pduListener); + } + + /** All done, release network resources */ + public void tearDownNetworkInterface() + { + disNetworkInterface.removeListener(pduListener); + disNetworkInterface.kill(); + disNetworkInterface = null; + } + + /** + * Send a single Protocol Data Unit (PDU) of any type + * @param pdu the pdu to send + */ + private void sendSinglePdu(Pdu pdu) + { + try + { + disNetworkInterface.send(pdu); + Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally + } + catch (InterruptedException ex) + { + System.err.println(this.getClass().getName() + " Error sending PDU: " + ex.getLocalizedMessage()); + System.exit(1); + } + } + + /** + * Send EntityState, Fire, Comment PDUs + * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments + * @param entityStatePdu the ESPDU to send, if any + * @param firePdu the FirePDU to send, if any + * @param commentType enumeration value describing the narrative comment + * @param comments String array of narrative comments + */ + public void sendAllPdus(EntityStatePdu entityStatePdu, + FirePdu firePdu, + VariableRecordType commentType, + // vararg... variable length string + String... comments) + { + if (entityStatePdu != null) + sendSinglePdu(entityStatePdu); + + if (firePdu != null) + sendSinglePdu(firePdu); // bang + + if ((comments != null) && (comments.length > 0)) + { + ArrayList<String> newCommentsList = new ArrayList<>(); + for (int i = 0; i < comments.length; i++) + { + if (!comments[i].isEmpty()) + newCommentsList.add(comments[i]); // OK found something to send + } + if (!newCommentsList.isEmpty()) + { + if (commentType == null) + commentType = VariableRecordType.OTHER; + CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments); + sendSinglePdu(commentPdu); + } + } + } + + /** + * Main method is first executed when a program instance is loaded. + * @see <a href="https://docs.oracle.com/javase/tutorial/getStarted/application/index.html">Java Tutorials: A Closer Look at the "Hello World!" Application</a> + * @param args command-line arguments are an array of optional String parameters that are passed from execution environment during invocation + */ + public static void main(String[] args) + { + ExampleSimulationProgram thisProgram = new ExampleSimulationProgram(); // creates instance + + // initial execution: can handle args array of initialization arguments here + if (args.length == 2) + { + if ((args[0] != null) && !args[0].isEmpty()) + thisProgram.setNetworkAddress(args[0]); + + if ((args[1] != null) && !args[1].isEmpty()) + thisProgram.setNetworkPort(Integer.parseInt(args[1])); + } + else if (args.length != 0) + { + System.err.println("Usage: " + thisProgram.getClass().getName() + " [address port]"); + System.exit(-1); + } + // OK here we go... + + thisProgram.setUpNetworkInterface(); + + thisProgram.runSimulation (); // customization code goes in there + + thisProgram.tearDownNetworkInterface(); + } + + /** + * Programmer-modifiable method for defining and running a new simulation of interest. + * Support include DIS EntityStatePdu, FirePdu and CommentPdu all available for + * modification and sending in a simulation loop. + */ + @SuppressWarnings("SleepWhileInLoop") + public void runSimulation () + { + try + { + final double LOOP_DURATION_SECONDS = 1.0; // seconds + final int MAX_LOOP_COUNT = 10; + int loopCount = 0; + VariableRecordType narrativeType = VariableRecordType.OTHER; // of potential use + boolean simulationComplete = false; // sentinel variable as termination condition + + // TODO reset clock to zero each time for consistent outputs. + + // your model setup: who's who in this zoo? + // create PDU objects and set their values + + EntityID entityID_1 = new EntityID(); + entityID_1.setSiteID(1).setApplicationID(2).setEntityID(3); // made-up example ID + + EntityStatePdu entityStatePdu = pduFactory.makeEntityStatePdu(); + entityStatePdu.setEntityID(entityID_1); + + FirePdu firePdu = pduFactory.makeFirePdu(); + // should we customize this munition? what is it for your simulation? + + while (loopCount < MAX_LOOP_COUNT) // loop the simulation while allowed, can set additional conditions to break + { + String narrativeMessage1, narrativeMessage2, narrativeMessage3; + // initialize loop variables + loopCount++; + + // ============================================================================================= + // your own simulation code starts here! + + // compute a track, update an ESPDU, whatever it is that your model is doing... + + // Where is my entity? + entityStatePdu.getEntityLocation().setX(entityStatePdu.getEntityLocation().getX() + 1.0); // 1m per timestep + + // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoort at! + + // etc. etc. your code goes here + + + + + + // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) + narrativeMessage1 = "MV3500 ExampleSimulationProgram"; + narrativeMessage2 = "runSimulation() loop " + loopCount; + narrativeMessage3 = ""; // intentionally blank for testing + + // your loop termination condition goes here + if (loopCount > 4) // for example + { + simulationComplete = true; + } + // your own simulation code is finished here! + // ============================================================================================= + + // keep track of timestep: wait duration for elapsed time in this loop + // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes + Thread.sleep((long)(LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds + System.out.println ("... Pausing for " + LOOP_DURATION_SECONDS + " seconds"); + + // send the status PDUs for this loop and continue + System.out.println ("sending PDUs for simulation step " + loopCount + ", monitor loopback to confirm sent"); + sendAllPdus(entityStatePdu, firePdu, null, narrativeMessage1, narrativeMessage2, narrativeMessage3); + System.out.println ("... PDUs successfully sent"); + + // =============================== + // loop now finished, thus terminate if simulation complete, otherwise send latest PDUs and continue + if (simulationComplete || (loopCount > 10000)) // for example; including fail-safe condition is good + { + System.out.println ("... Termination condition met, simulationComplete=" + simulationComplete); + break; + } + } // end of while loop + } + catch (Exception ex) // handle any exception that your code might choose to provoke! + { + Logger.getLogger(ExampleSimulationProgram.class.getName()).log(Level.SEVERE, null, ex); + } + } +} diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgramOutput.txt b/examples/src/OpenDis7Examples/ExampleSimulationProgramOutput.txt new file mode 100644 index 0000000000000000000000000000000000000000..4b655f0b2cbea5e7117351b7f87e2ae96ff9b7b2 --- /dev/null +++ b/examples/src/OpenDis7Examples/ExampleSimulationProgramOutput.txt @@ -0,0 +1,44 @@ +ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis7Examples/ExampleSimulationProgram.java -Drun.class=OpenDis7Examples.ExampleSimulationProgram run-single +init: +Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +deps-jar: +Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties +Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes +warning: [options] bootstrap class path not set in conjunction with -source 8 +1 warning +compile-single: +run-single: +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] Using network interface Intel(R) Dual Band Wireless-AC 8260 +Network confirmation: address=239.1.2.3 port=3000 +... Pausing for 1.0 seconds +sending PDUs for simulation step 1, monitor loopback to confirm sent +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 1. received DISPDUType 1 ENTITY_STATE (timestamp 19:36:11, size 144 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 2. received DISPDUType 2 FIRE (timestamp 19:36:18, size 96 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 3. received DISPDUType 22 COMMENT (timestamp 20:00:13, size 104 bytes) +... PDUs successfully sent +... Pausing for 1.0 seconds +sending PDUs for simulation step 2, monitor loopback to confirm sent +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 4. received DISPDUType 1 ENTITY_STATE (timestamp 19:36:11, size 144 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 5. received DISPDUType 2 FIRE (timestamp 19:36:18, size 96 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 6. received DISPDUType 22 COMMENT (timestamp 20:26:12, size 104 bytes) +... PDUs successfully sent +... Pausing for 1.0 seconds +sending PDUs for simulation step 3, monitor loopback to confirm sent +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 7. received DISPDUType 1 ENTITY_STATE (timestamp 19:36:11, size 144 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 8. received DISPDUType 2 FIRE (timestamp 19:36:18, size 96 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 9. received DISPDUType 22 COMMENT (timestamp 20:52:09, size 104 bytes) +... PDUs successfully sent +... Pausing for 1.0 seconds +sending PDUs for simulation step 4, monitor loopback to confirm sent +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 10. received DISPDUType 1 ENTITY_STATE (timestamp 19:36:11, size 144 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 11. received DISPDUType 2 FIRE (timestamp 19:36:18, size 96 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 12. received DISPDUType 22 COMMENT (timestamp 21:18:03, size 104 bytes) +... PDUs successfully sent +... Pausing for 1.0 seconds +sending PDUs for simulation step 5, monitor loopback to confirm sent +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 13. received DISPDUType 1 ENTITY_STATE (timestamp 19:36:11, size 144 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 14. received DISPDUType 2 FIRE (timestamp 19:36:18, size 96 bytes) +[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 15. received DISPDUType 22 COMMENT (timestamp 21:43:59, size 104 bytes) +... PDUs successfully sent +... Termination condition met, simulationComplete=true +BUILD SUCCESSFUL (total time: 10 seconds) diff --git a/examples/src/OpenDis7Examples/PduListenerSaver.java b/examples/src/OpenDis7Examples/PduListenerSaver.java index 3e0f35a7b7c7bcc02d845af76e3608f22d4e7782..769f82e140057da5c3b8d88ece6335a9c973e5eb 100644 --- a/examples/src/OpenDis7Examples/PduListenerSaver.java +++ b/examples/src/OpenDis7Examples/PduListenerSaver.java @@ -36,7 +36,7 @@ public class PduListenerSaver String multicastAddress = DEFAULT_MULTICAST_ADDRESS; int multicastPort = DEFAULT_MULTICAST_PORT; - System.out.println("DisExamplesOpenDis7.PduListenerSaver started..."); + System.out.println("OpenDis7Examples.PduListenerSaver started..."); switch (args.length) { case 0: @@ -67,18 +67,27 @@ public class PduListenerSaver if (line.equalsIgnoreCase("p") && state == mystate.RUNNING) { recorder.stopPause(); state = mystate.PAUSED; + System.out.println("... now PAUSED"); + } + else if (line.equalsIgnoreCase("p")) { + System.out.println("... still PAUSED"); } else if (line.equalsIgnoreCase("r") && state == mystate.PAUSED) { recorder.startResume(); state = mystate.RUNNING; + System.out.println("... now RUNNING"); + } + else if (line.equalsIgnoreCase("r")) { + System.out.println("... still RUNNING"); } else if (line.equalsIgnoreCase("q")) { + System.out.println("... QUIT"); recorder.end(); break; } } System.out.println("Ending PduListenerSaver pdu recording, saved to file:"); - System.out.println(recorder.getLogFile()); + System.out.println(recorder.getLogFilePath()); } catch (IOException ex) { System.err.println("Exception: " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage()); diff --git a/examples/src/OpenDis7Examples/PduReaderPlayer.java b/examples/src/OpenDis7Examples/PduReaderPlayer.java index bdfc3c568c576e3bedaf95e4c9736be1044ab482..9564e2fc8918f707eb7e500a559b7a4db02ec473 100644 --- a/examples/src/OpenDis7Examples/PduReaderPlayer.java +++ b/examples/src/OpenDis7Examples/PduReaderPlayer.java @@ -38,7 +38,7 @@ public class PduReaderPlayer int multicastPort = DEFAULT_MULTICAST_PORT; boolean sendToNet = false; - System.out.println("DisExamplesOpenDis7.PduReaderPlayer started..."); + System.out.println("OpenDis7Examples.PduReaderPlayer started..."); switch (args.length) { case 0: @@ -84,7 +84,7 @@ public class PduReaderPlayer } } System.out.println("Ending pdu files playback for directory " + outputDirectory); - System.out.println("DisExamplesOpenDis7.PduReaderPlayer complete."); + System.out.println("OpenDis7Examples.PduReaderPlayer complete."); System.exit(0); // not sure why this is necessary with Netbeans... } catch (IOException ex) { diff --git a/examples/src/TcpExamples/TcpExample4Client.java b/examples/src/TcpExamples/TcpExample4Client.java index 8b29a7336ec8ed99150ac41cc89e580fbe4b1b96..87ba53107d0549a60af3a3784da45139a004f49d 100644 --- a/examples/src/TcpExamples/TcpExample4Client.java +++ b/examples/src/TcpExamples/TcpExample4Client.java @@ -13,8 +13,8 @@ import java.net.*; * @author MV3500 class */ public class TcpExample4Client { - - static int MAX_LOOP_COUNT = 4; + static String DESTINATION_HOST = "localhost"; + static int MAX_LOOP_COUNT = 4; public static void main(String[] args) { try { @@ -34,7 +34,7 @@ public class TcpExample4Client { long startTime = System.currentTimeMillis(); // open a socket for each loop - Socket socket = new Socket("localhost", 2317); + Socket socket = new Socket(DESTINATION_HOST, 2317); // Setup. Read the single line written by the server. // We'd do things a bit differently if many lines to be read diff --git a/examples/src/UdpMulticastExamples/MulticastReceiver.java b/examples/src/UdpMulticastExamples/MulticastReceiver.java index 9a49f52b51e747452296682b20d93378419028ac..9c8716d99de7e3cb373803f502447850a8604cc0 100644 --- a/examples/src/UdpMulticastExamples/MulticastReceiver.java +++ b/examples/src/UdpMulticastExamples/MulticastReceiver.java @@ -1,6 +1,6 @@ package UdpMulticastExamples; -import edu.nps.moves.dis7.utilities.DisThreadedNetIF; +import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface; import java.io.*; import java.net.*; import java.nio.ByteBuffer; @@ -19,7 +19,7 @@ public class MulticastReceiver { // https://en.wikipedia.org/wiki/Multicast_address // https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml public static final String MULTICAST_ADDRESS = "239.1.2.15"; - public static final int DESTINATION_PORT = 1718; + public static final int DESTINATION_PORT = 1718; /** * Time to live: how many router-decrement levels can be crossed @@ -53,7 +53,7 @@ public class MulticastReceiver { group = new InetSocketAddress(multicastAddress, DESTINATION_PORT); // Join group useful on receiving side - multicastSocket.joinGroup(group, ni = DisThreadedNetIF.findIpv4Interface()); + multicastSocket.joinGroup(group, ni = DisThreadedNetworkInterface.findIpv4Interface()); // You can join multiple groups here System.out.println("Multicast address/port: " + multicastAddress.getHostAddress() + "/" + DESTINATION_PORT); diff --git a/examples/src/UdpMulticastExamples/MulticastSender.java b/examples/src/UdpMulticastExamples/MulticastSender.java index ef698d274c20274df27d411d240bcc451add523f..b4021f019653f418edf6b2d891d0ed84848f6984 100644 --- a/examples/src/UdpMulticastExamples/MulticastSender.java +++ b/examples/src/UdpMulticastExamples/MulticastSender.java @@ -1,6 +1,6 @@ package UdpMulticastExamples; -import edu.nps.moves.dis7.utilities.DisThreadedNetIF; +import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface; import java.io.*; import java.net.*; import java.util.logging.Level; @@ -62,7 +62,7 @@ public class MulticastSender { group = new InetSocketAddress(multicastAddress, DESTINATION_PORT); // Join group useful on receiving side - multicastSocket.joinGroup(group, ni = DisThreadedNetIF.findIpv4Interface()); + multicastSocket.joinGroup(group, ni = DisThreadedNetworkInterface.findIpv4Interface()); // You can join multiple groups here byte[] buffer = baos.toByteArray(); diff --git a/lib/README.md b/lib/README.md index cd707cfc5df225401b304009e248c96e7c74d8f7..235c7b488556a0daf333dcf0a75a0bf11f73f0ed 100644 --- a/lib/README.md +++ b/lib/README.md @@ -1,3 +1,8 @@ ## 'lib' project library directory This directory contains library jar files used by each of the course project directories. + +Of note: + +* open-dis7-enumerations jar files contain all [SISO-REF-010](../specifications/README.md) values with sources automatically created from authoritative SISO XML as part of [open-dis7-source-generator](https://github.com/open-dis/open-dis7-source-generator) project +* open-dis7-java jar files contain all [IEEE PDU packet types](../specifications/IeeeDisPduColorFigures.pdf), with sources automatically created from [XML descriptions](https://github.com/open-dis/open-dis7-source-generator/tree/master/xml) and results collected as part of [open-dis7-java](https://github.com/open-dis/open-dis7-java) project diff --git a/lib/open-dis7-enumerations-classes.jar b/lib/open-dis7-enumerations-classes.jar new file mode 100644 index 0000000000000000000000000000000000000000..31530698b56fb4f3c082f53d586fa206fff23d52 Binary files /dev/null and b/lib/open-dis7-enumerations-classes.jar differ diff --git a/lib/open-dis7-enumerations-javadoc.jar b/lib/open-dis7-enumerations-javadoc.jar new file mode 100644 index 0000000000000000000000000000000000000000..62c10d5c86e54a6c1385ac58d1b3ea933d696497 Binary files /dev/null and b/lib/open-dis7-enumerations-javadoc.jar differ diff --git a/lib/open-dis7-entities-all.jar b/lib/open-dis7-enumerations-source.jar similarity index 63% rename from lib/open-dis7-entities-all.jar rename to lib/open-dis7-enumerations-source.jar index bf060b7480f219bcd0d821c1a466e257a81bd33e..312eefb8cb21e01b7d7203a2f47963c4d3a96964 100644 Binary files a/lib/open-dis7-entities-all.jar and b/lib/open-dis7-enumerations-source.jar differ diff --git a/lib/open-dis7-java.jar b/lib/open-dis7-java.jar deleted file mode 100644 index 638d31ec50395d2c1989181448740e172623e307..0000000000000000000000000000000000000000 Binary files a/lib/open-dis7-java.jar and /dev/null differ diff --git a/lib/open-dis7-javadoc.jar b/lib/open-dis7-javadoc.jar deleted file mode 100644 index 13feb1093d169886bf4b75134debadf3ec838717..0000000000000000000000000000000000000000 Binary files a/lib/open-dis7-javadoc.jar and /dev/null differ diff --git a/lib/open-dis7-pdus-classes.jar b/lib/open-dis7-pdus-classes.jar new file mode 100644 index 0000000000000000000000000000000000000000..982cfa4432d04b9117c6b2e05082b6e4db54c284 Binary files /dev/null and b/lib/open-dis7-pdus-classes.jar differ diff --git a/lib/open-dis7-pdus-javadoc.jar b/lib/open-dis7-pdus-javadoc.jar new file mode 100644 index 0000000000000000000000000000000000000000..19cb9d3343353dfdf02b222b09b57d15a8cd6ff7 Binary files /dev/null and b/lib/open-dis7-pdus-javadoc.jar differ diff --git a/lib/open-dis7-pdus-source.jar b/lib/open-dis7-pdus-source.jar new file mode 100644 index 0000000000000000000000000000000000000000..7a969003b81a82756802b53614b63786a7a490e5 Binary files /dev/null and b/lib/open-dis7-pdus-source.jar differ diff --git a/lib/open-dis7-source.jar b/lib/open-dis7-source.jar deleted file mode 100644 index 9083bdab1ff543838b86fa222d998ff873efe86c..0000000000000000000000000000000000000000 Binary files a/lib/open-dis7-source.jar and /dev/null differ diff --git a/nbproject/jdk.xml b/nbproject/jdk.xml new file mode 100644 index 0000000000000000000000000000000000000000..3d29141bdc5618925dfb987183238a1d3ee92bde --- /dev/null +++ b/nbproject/jdk.xml @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8"?><project name="jdk" basedir="."> + + + <description> + Permits selection of a JDK to use when building and running project. + See: http://www.netbeans.org/issues/show_bug.cgi?id=64160 + </description> + + <target name="-jdk-pre-preinit"> + <condition property="nbjdk.active-or-nbjdk.home"> + <or> + <and> + <isset property="nbjdk.active"/> + <not> + <equals arg1="${nbjdk.active}" arg2="default_platform"/> + </not> + </and> + <and> + <isset property="nbjdk.home"/> + <not> + <isset property="nbjdk.home.defaulted"/> + </not> + </and> + </or> + </condition> + </target> + + <target xmlns:common="http://java.netbeans.org/freeform/jdk.xml" name="-jdk-preinit" depends="-jdk-pre-preinit" if="nbjdk.active-or-nbjdk.home"> + <macrodef name="property" uri="http://java.netbeans.org/freeform/jdk.xml"> + <attribute name="name"/> + <attribute name="value"/> + <sequential> + <property name="@{name}" value="${@{value}}"/> + </sequential> + </macrodef> + <common:property name="nbjdk.home" value="platforms.${nbjdk.active}.home"/> + <common:property name="nbjdk.javac.tmp" value="platforms.${nbjdk.active}.javac"/> + <condition property=".exe" value=".exe"> + <os family="windows"/> + </condition> + <property name=".exe" value=""/> + <condition property="nbjdk.javac" value="${nbjdk.home}/bin/javac${.exe}"> + <equals arg1="${nbjdk.javac.tmp}" arg2="$${platforms.${nbjdk.active}.javac}"/> + </condition> + <property name="nbjdk.javac" value="${nbjdk.javac.tmp}"/> + <common:property name="nbjdk.java.tmp" value="platforms.${nbjdk.active}.java"/> + <condition property="nbjdk.java" value="${nbjdk.home}/bin/java${.exe}"> + <equals arg1="${nbjdk.java.tmp}" arg2="$${platforms.${nbjdk.active}.java}"/> + </condition> + <property name="nbjdk.java" value="${nbjdk.java.tmp}"/> + <common:property name="nbjdk.javadoc.tmp" value="platforms.${nbjdk.active}.javadoc"/> + <condition property="nbjdk.javadoc" value="${nbjdk.home}/bin/javadoc${.exe}"> + <equals arg1="${nbjdk.javadoc.tmp}" arg2="$${platforms.${nbjdk.active}.javadoc}"/> + </condition> + <property name="nbjdk.javadoc" value="${nbjdk.javadoc.tmp}"/> + <common:property name="nbjdk.bootclasspath.tmp" value="platforms.${nbjdk.active}.bootclasspath"/> + <condition property="nbjdk.bootclasspath" value="${nbjdk.home}/jre/lib/rt.jar"> + <equals arg1="${nbjdk.bootclasspath.tmp}" arg2="$${platforms.${nbjdk.active}.bootclasspath}"/> + </condition> + <property name="nbjdk.bootclasspath" value="${nbjdk.bootclasspath.tmp}"/> + <condition property="nbjdk.valid"> + <and> + <available file="${nbjdk.home}" type="dir"/> + <available file="${nbjdk.javac}" type="file"/> + <available file="${nbjdk.java}" type="file"/> + <available file="${nbjdk.javadoc}" type="file"/> + + </and> + </condition> + <echo level="verbose">nbjdk.active=${nbjdk.active} nbjdk.home=${nbjdk.home} nbjdk.java=${nbjdk.java} nbjdk.javac=${nbjdk.javac} nbjdk.javadoc=${nbjdk.javadoc} nbjdk.bootclasspath=${nbjdk.bootclasspath} nbjdk.valid=${nbjdk.valid} have-jdk-1.4=${have-jdk-1.4} have-jdk-1.5=${have-jdk-1.5}</echo> + </target> + + <target name="-jdk-warn" depends="-jdk-preinit" if="nbjdk.active-or-nbjdk.home" unless="nbjdk.valid"> + <property name="jdkhome.presumed" location="${java.home}/.."/> + <echo level="warning">Warning: nbjdk.active=${nbjdk.active} or nbjdk.home=${nbjdk.home} is an invalid Java platform; ignoring and using ${jdkhome.presumed}</echo> + </target> + + <target name="-jdk-presetdef-basic" depends="-jdk-preinit" if="nbjdk.valid" unless="nbjdk.presetdef.basic.done"> + + + <macrodef name="javac-presetdef"> + <attribute name="javacval"/> + <sequential> + <presetdef name="javac"> + <javac fork="yes" executable="@{javacval}"/> + </presetdef> + </sequential> + </macrodef> + <javac-presetdef javacval="${nbjdk.javac}"/> + <macrodef name="java-presetdef"> + <attribute name="javaval"/> + <sequential> + <presetdef name="java"> + <java fork="yes" jvm="@{javaval}"/> + </presetdef> + </sequential> + </macrodef> + <java-presetdef javaval="${nbjdk.java}"/> + <macrodef name="javadoc-presetdef"> + <attribute name="javadocval"/> + <sequential> + <presetdef name="javadoc"> + <javadoc executable="@{javadocval}"/> + </presetdef> + </sequential> + </macrodef> + <javadoc-presetdef javadocval="${nbjdk.javadoc}"/> + <macrodef name="junit-presetdef"> + <attribute name="javaval"/> + <sequential> + <presetdef name="junit"> + <junit fork="yes" jvm="@{javaval}"/> + </presetdef> + </sequential> + </macrodef> + <junit-presetdef javaval="${nbjdk.java}"/> + <property name="nbjdk.presetdef.basic.done" value="true"/> + </target> + + <target name="-jdk-presetdef-nbjpdastart" depends="-jdk-preinit" if="nbjdk.valid" unless="nbjdk.presetdef.nbjpdastart.done"> + <macrodef name="nbjpdastart-presetdef"> + <attribute name="bootcpval"/> + <sequential> + <presetdef name="nbjpdastart"> + <nbjpdastart> + <bootclasspath> + <path path="@{bootcpval}"/> + </bootclasspath> + </nbjpdastart> + </presetdef> + </sequential> + </macrodef> + <nbjpdastart-presetdef bootcpval="${nbjdk.bootclasspath}"/> + <property name="nbjdk.presetdef.nbjpdastart.done" value="true"/> + </target> + + <target name="-jdk-default" unless="nbjdk.active-or-nbjdk.home"> + + <property name="java.home.parent" location="${java.home}/.."/> + <condition property="nbjdk.home" value="${java.home.parent}"> + <available file="${java.home.parent}/lib/tools.jar" type="file"/> + </condition> + <condition property="nbjdk.home" value="${java.home}"> + <available file="${java.home}/lib/tools.jar" type="file"/> + </condition> + + <condition property="nbjdk.home" value="/Library/Java/Home"> + <available file="/Library/Java/Home" type="dir"/> + </condition> + + <property name="nbjdk.home" location="${java.home.parent}"/> + <property name="nbjdk.home.defaulted" value="true"/> + </target> + + <target name="-jdk-init" depends="-jdk-preinit,-jdk-warn,-jdk-presetdef-basic,-jdk-default"/> + +</project> \ No newline at end of file diff --git a/nbproject/nbjdk.properties b/nbproject/nbjdk.properties new file mode 100644 index 0000000000000000000000000000000000000000..3033a8abbe8c94d80e50e14c39c869aee52fbf88 --- /dev/null +++ b/nbproject/nbjdk.properties @@ -0,0 +1 @@ +nbjdk.active=default_platform diff --git a/nbproject/nbjdk.xml b/nbproject/nbjdk.xml new file mode 100644 index 0000000000000000000000000000000000000000..22ced4d044b466209fa9187daaadc4dd58d600b5 --- /dev/null +++ b/nbproject/nbjdk.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project basedir=".." name="Networked_Graphics_MV3500"> + <property file="nbproject/nbjdk.properties"/> + <property location="${netbeans.user}/build.properties" name="user.properties.file"/> + <property file="${user.properties.file}"/> + <import file="jdk.xml"/> +</project> diff --git a/nbproject/project.xml b/nbproject/project.xml index 1c6ab13dbb8ab5e23e9bfffbdb691e8a6ce13002..cc787cf98ddbe463797aca941d471d42353d9e14 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -6,11 +6,11 @@ <name>Networked Graphics MV3500</name> </general-data> <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2"> - <!-- Do not use Project Properties customizer when editing this file manually. - To prevent the customizer from showing, create nbproject/project.properties file and enter -auxiliary.show.customizer=false -property there. Adding -auxiliary.show.customizer.message=<message> + <!-- Do not use Project Properties customizer when editing this file manually. + To prevent the customizer from showing, create nbproject/project.properties file and enter +auxiliary.show.customizer=false +property there. Adding +auxiliary.show.customizer.message=<message> will show your customized message when someone attempts to open the customizer. --> <name>Networked Graphics MV3500</name> <properties/> diff --git a/presentations/07_NetworkScalability.pptx b/presentations/07_NetworkScalability.pptx index e87e14b138acfeea4204c4726317f88791feedbf..28bf26c20ecab765e034c1e850ffc0d770628809 100644 Binary files a/presentations/07_NetworkScalability.pptx and b/presentations/07_NetworkScalability.pptx differ diff --git a/presentations/09_HLA_HighLevelArchitecture.pptx b/presentations/09_HLA_HighLevelArchitecture.pptx index f12d1cfa868999d0ed769de2dc83ac2b23d4a1fc..8848d70975110b82069944936cdd0d22d61db1a5 100644 Binary files a/presentations/09_HLA_HighLevelArchitecture.pptx and b/presentations/09_HLA_HighLevelArchitecture.pptx differ diff --git a/presentations/11a_Certificates_PKI.ppt b/presentations/11a_Certificates_PKI.ppt index d0ba4c811050d5397d4ff42ee001bdf49ee38521..87fdd5f718ddbfc78cae509a74b6201152bb5c67 100644 Binary files a/presentations/11a_Certificates_PKI.ppt and b/presentations/11a_Certificates_PKI.ppt differ diff --git a/presentations/11b_SimulationAsAService.ppt b/presentations/11b_SimulationAsAService.ppt index 7c98623b424a575eda509d19f6c3bfda2e0f781b..5d79dcaf46cc6148c0113a6af4be0f2a4684ff5f 100644 Binary files a/presentations/11b_SimulationAsAService.ppt and b/presentations/11b_SimulationAsAService.ppt differ diff --git a/presentations/11c_Clouds_Virtualization.ppt b/presentations/11c_Clouds_Virtualization.ppt index 91da6e887d932ad3650e47968e0b3c17b50eb43a..c53c860c87112a032624057c6a40d404c6059285 100644 Binary files a/presentations/11c_Clouds_Virtualization.ppt and b/presentations/11c_Clouds_Virtualization.ppt differ diff --git a/specifications/IeeeDisPduColorFigures.pdf b/specifications/IeeeDisPduColorFigures.pdf index cc0e26046238267d8355ba34fa31225882413648..0a137b0d745e9b9e450d407a18dd2c15ba561942 100644 Binary files a/specifications/IeeeDisPduColorFigures.pdf and b/specifications/IeeeDisPduColorFigures.pdf differ diff --git a/specifications/README.md b/specifications/README.md index 984da8c081210a29130a1f8c4515fc10f4280848..544540b031becf4165593e065a9c703a47b4ba5c 100644 --- a/specifications/README.md +++ b/specifications/README.md @@ -1,16 +1,17 @@ # IEEE Distributed Interactive Simulation (DIS) Protocol -*Distributed Interactive Simulation (DIS) is an IEEE standard for conducting +*Distributed Interactive Simulation (DIS) is an +[Institute of Electrical and Electronics Engineers (IEEE)](https://www.ieee.org) standard for conducting real-time platform-level wargaming across multiple host computers and is used worldwide, especially by military organizations but also by other agencies such as those involved in space exploration and medicine.* * Wikipedia: [Distributed Interactive Simulation (DIS)](https://en.wikipedia.org/wiki/Distributed_Interactive_Simulation) IEEE Standard and [RPR FOM](https://en.wikipedia.org/wiki/RPR_FOM) * [Simulation Interoperabilty Standards Organization (SISO)](https://www.sisostds.org): "Simulation Interoperability and Reuse through Standards" -* SISO Product Support Group (PSG): [DIS / RPR FOM PSG - Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model](https://www.sisostds.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx) +* SISO [DIS / RPR FOM PSG - Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model](https://www.sisostds.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx) Product Support Group (PSG) ## Working-Group Resources -**DIS/RPR FOM Product Support Group** +**DIS/RPR FOM Product Support Group** <img src="SisoLogo.jpg" width="314" align="right"/> * "The Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model (DIS / RPR FOM) Product Support Group (PSG) is a permanent support group chartered by the SISO Standards Activity Committee to support multiple DIS-related products." * [Distributed Interactive Simulation / Real-time Platform Reference Federation Object Model (DIS / RPR FOM) Product Support Group (PSG)](https://www.sisostds.org/StandardsActivities/SupportGroups/DISRPRFOMPSG.aspx) @@ -37,7 +38,7 @@ Data messages, known as Protocol Data Units (PDUs), that are exchanged on a netw --- -**1278.2-2015. IEEE Standard for Distributed Interactive Simulation (DIS) - Communication Services and Profiles** +**1278.2-2015. IEEE Standard for Distributed Interactive Simulation (DIS) - Communication Services and Profiles** <img src="IeeeLogo.jpg" width="120" align="right"/> * https://ieeexplore.ieee.org/document/7459689 * *Abstract.* Communication services to support information exchange between simulation applications participating in the distributed interactive simulation (DIS) environment are defined. These communication services describe a connectionless information transfer that supports real-time, as well as non-real-time, exchange. Several communication profiles specifying communication services are provided. @@ -50,7 +51,7 @@ The purpose of this standard is to establish requirements for communication subs --- -**1278.3-1996. IEEE Recommended Practice for Distributed Interactive Simulation - Exercise Management and Feedback** +**1278.3-1996. IEEE Recommended Practice for Distributed Interactive Simulation - Exercise Management and Feedback** <img src="IeeeLogo.jpg" width="120" align="right"/> * https://ieeexplore.ieee.org/document/587529 * *Abstract.* Guidelines are established for exercise management and feedback in distributed interactive simulation (DIS) exercises. Guidance is provided to sponsors, providers and supporters of DIS-compliant systems and exercises as well as to developers of DIS exercise management and feedback stations. The activities of the organizations involved in a DIS exercise and the top-level processes used to accomplish those activities are addressed. The functional requirements of the exercise management and feedback process are also addressed. This standard is one of a series of standards developed for DIS to assure interoperability between dissimilar simulations for currently installed and future simulations developed by different organizations. @@ -58,7 +59,7 @@ Guidelines are established for exercise management and feedback in distributed i --- -**4. 1278.4-1997. IEEE Recommended Practice for Distributed Interactive Simulation - Verification, Validation, and Accreditation** +**4. 1278.4-1997. IEEE Recommended Practice for Distributed Interactive Simulation - Verification, Validation, and Accreditation** <img src="IeeeLogo.jpg" width="120" align="right"/> * https://ieeexplore.ieee.org/document/8685803 * *Abstract.* Guidelines are established for the verification, validation, and accreditation (VV&A) of distributed interactive simulation (DIS) exercises. How-to procedures for planning and conducting DIS exercise VV&A are provided. Intended for use in conjunction with IEEE Std 1278.3-1996, this recommended practice presents data flow and connectivity for all proposed verification and validation activities and provides rationale and justification for each step. VV&A guidance is provided to exercise users/sponsors and developers. @@ -67,9 +68,12 @@ Guidelines are established for the verification, validation, and accreditation ( --- -**5. SISO-REF-010-2019: Reference for Enumerations for Simulation Interoperability** <img src="SisoLogo.jpg" width="314" align="right"/> -* https://www.sisostds.org/ProductsPublications/ReferenceDocuments.aspx +**5. SISO-REF-010-2020: Reference for Enumerations for Simulation Interoperability** <img src="SisoLogo.jpg" width="314" align="right"/> +* https://www.sisostds.org/ProductsPublications/ReferenceDocuments.aspx (scroll down to bottom of page) * *Abstract.* SISO-REF-010 specifies numerical values and associated definitions for fields that are identified as enumerations in SISO Standards Products and SISO-sponsored standards published by IEEE for High Level Architecture (HLA) and Distributed Interactive Simulation (DIS). Enumerations for simulations may be applied in other architectures, such as the Test and Training Enabling Architecture (TENA). +* Resources include [SISO-REF-010-2020 distribution](https://www.sisostds.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=51787), +[enumerations PDF](https://www.sisostds.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=46172) and +[Operations Manual (OPMAN)](https://www.sisostds.org/DigitalLibrary.aspx?Command=Core_Download&EntryId=47284) --- diff --git a/specifications/build.xml b/specifications/build.xml index c1075129222aaa183706a74a7daa481aa85db489..d4910393bb9d6a86598458f76b0e359b21fb62b9 100644 --- a/specifications/build.xml +++ b/specifications/build.xml @@ -17,25 +17,39 @@ <fileset dir="." includes="**/*.xsl"/> <fileset dir="." includes="**/Makefile"/> <fileset dir="." includes="**/README.txt"/> - <fileset dir="." includes="**/SISO-REF-010-2019*/*"/> + <fileset dir="." includes="**/SISO-REF-010-v28/*"/> </delete> - <delete verbose="true" failonerror="false" dir="SISO-REF-010-2019 Enumerations v26_files"/> + <delete verbose="true" failonerror="false" dir="SISO-REF-010-v28"/> </target> <!-- =============================================== --> <target name="download.IeeeDisStandards.rename" description="rename saved DIS specification files to readable filenames"> - <move file="6387564.pdf" tofile="IEEE1278.1-2012.DistributedInteractiveSimulation.ApplicationProtocols.6387564.pdf" verbose="true" quiet="true" failonerror="false"/> - <move file="7459689.pdf" tofile="IEEE1278.2-2015.DistributedInteractiveSimulation.CommunicationsServices.7459689.pdf" verbose="true" quiet="true" failonerror="false"/> - <move file= "587529.pdf" tofile="IEEE1278.3-2015.DistributedInteractiveSimulation.CommunicationsServices.587529.pdf" verbose="true" quiet="true" failonerror="false"/> - <move file="6595010.pdf" tofile="IEEE1278.4-2013.DistributedInteractiveSimulation.VV+A.8685803.pdf" verbose="true" quiet="true" failonerror="false"/> + <!-- part 1 6387564.pdf --> + <move file="12781-2012.pdf" tofile="IEEE1278.1-2012.DistributedInteractiveSimulation.ApplicationProtocols.12781-2012.pdf" verbose="true" quiet="true" failonerror="false"/> + <copy todir="archive" file="IEEE1278.1-2012.DistributedInteractiveSimulation.ApplicationProtocols.12781-2012.pdf" verbose="true" quiet="true" failonerror="false"/> + <!-- part 2 7459689.pdf --> + <move file="12782-2015.pdf" tofile="IEEE1278.2-2015.DistributedInteractiveSimulation.CommunicationsServices.12782-2015.pdf" verbose="true" quiet="true" failonerror="false"/> + <copy todir="archive" file="IEEE1278.2-2015.DistributedInteractiveSimulation.CommunicationsServices.12782-2015.pdf" verbose="true" quiet="true" failonerror="false"/> + <!-- part 3 00587529.pdf --> + <move file= "00587529.pdf" tofile="IEEE1278.3-2015.DistributedInteractiveSimulation.CommunicationsServices.00587529.pdf" verbose="true" quiet="true" failonerror="false"/> + <copy todir="archive" file="IEEE1278.3-2015.DistributedInteractiveSimulation.CommunicationsServices.00587529.pdf" verbose="true" quiet="true" failonerror="false"/> + <!-- part 4 6595010.pdf --> + <move file="12784-1997.pdf" tofile="IEEE1278.4-2013.DistributedInteractiveSimulation.VV+A.12784-1997.pdf" verbose="true" quiet="true" failonerror="false"/> + <copy todir="archive" file="IEEE1278.4-2013.DistributedInteractiveSimulation.VV+A.12784-1997.pdf" verbose="true" quiet="true" failonerror="false"/> - <echo message="*.pdf directory contents:"/> + <echo message="check *.pdf directory contents..."/> <!-- https://stackoverflow.com/questions/10528032/listing-all-files-and-subdirectories-using-ant --> <fileset id="dist.contents" dir="." includes="*.pdf"/> <property name="prop.dist.contents" refid="dist.contents"/> <!-- https://stackoverflow.com/questions/7102793/how-to-put-a-newline-in-ant-property --> + <echo message="specifications directory:"/> <echo message="${prop.dist.contents}"/> + <fileset id="archive.contents" dir="archive" includes="*.pdf"/> + <property name="prop.archive.contents" refid="archive.contents"/> + <!-- https://stackoverflow.com/questions/7102793/how-to-put-a-newline-in-ant-property --> + <echo message="specifications/archive directory:"/> + <echo message="${prop.archive.contents}"/> </target> <!-- =============================================== --> @@ -46,8 +60,8 @@ <property name="ieeeBasePageUrl" value="https://ieeexplore.ieee.org/document/"/> <property name="ieeeBaseLinkUrl" value="https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber="/> - <echo message="Warning: due to cookie restrictions, you must download IEEE specifications manually via links found in README.md"/> - <echo message="TODO? University students/faculty can first login with permissions to the IEEE Explore page, then use target download.IeeeDisStandards.retrieve"/> + <echo message="Warning: due to cookie and scripting restrictions, you must download IEEE specifications manually via links found in README.md"/> + <echo message="TODO: university students/faculty can first login with permissions to the IEEE Explore page, then use target download.IeeeDisStandards.retrieve"/> <echo message="IEEE Explore: ${ieeeExploreUrl}"/> <!-- ======================== --> @@ -62,6 +76,7 @@ <property name="warningMessage" value="Restriction: cookie restrictions prevent automated download. You must manually download this file while within NPS campus or firewall. For "/> <echo message="${warningMessage}IEEE1278.1 retrieval to this location, use your browser to save ${ieeeBaseLinkUrl}${DIS.1.document}" file="${DIS.1.rename}.SAVEME"/> + <echo message=""/> <!-- ======================== --> <property name="DIS.2.document" value="7459689"/> @@ -74,6 +89,7 @@ dest="${DIS.2.rename}" verbose="true"/> --> <echo message="${warningMessage}IEEE1278.2 retrieval to this location, use your browser to save ${ieeeBaseLinkUrl}${DIS.2.document}" file="${DIS.2.rename}"/> + <echo message=""/> <!-- ======================== --> <property name="DIS.3.document" value="587529"/> @@ -86,6 +102,7 @@ dest="${DIS.3.rename}" verbose="true"/> --> <echo message="${warningMessage}IEEE1278.3 retrieval to this location, use your browser to save ${ieeeBaseLinkUrl}${DIS.3.document}" file="${DIS.3.rename}"/> + <echo message=""/> <!-- ======================== --> <property name="DIS.4.document" value="8685803"/> @@ -119,7 +136,7 @@ <echo message="as ${DIS.1.rename}"/> <get src="${ieeeBaseLinkUrl}${DIS.1.document}" dest="${DIS.1.rename}" verbose="true"/> - + <!-- ======================== --> <property name="DIS.2.document" value="7459689"/> <property name="DIS.2.rename" value="IEEE1278.2-2015.DistributedInteractiveSimulation.CommunicationsServices.${DIS.2.document}.pdf"/> @@ -153,21 +170,26 @@ <property name="sisoBaseUrl" value="https://www.sisostds.org/DigitalLibrary.aspx?Command=Core_Download&EntryId="/> <target name="download.SISO"> - - <property name="SISO-REF-010" value="SISO-REF-010-v26.zip"/> - <echo message="get ${SISO-REF-010}"/> - <get src="${sisoBaseUrl}46171" - dest="${SISO-REF-010}" verbose="true"/> - <unzip src="${SISO-REF-010}" - dest="" overwrite="true"/> - <delete file="${SISO-REF-010}"/> + <property name="SISO-REF-010" value="SISO-REF-010-v28"/> + <delete dir="${SISO-REF-010}" failonerror="false"/> + <mkdir dir="${SISO-REF-010}"/> + <echo message="get ${SISO-REF-010}.zip from"/> + <echo message=" ${sisoBaseUrl}51787"/> + <get src="${sisoBaseUrl}51787" + dest="${SISO-REF-010}.zip" verbose="true"/> + <unzip src="${SISO-REF-010}.zip" + dest="${SISO-REF-010}" overwrite="true"/> + <delete file="${SISO-REF-010}.zip"/><!-- no longer needed --> - <!-- duplicative, already contained in preceding zip + <!-- ensure not duplicative and already contained in preceding zip --> <property name="SISO-REF-010.1" value="SISO-REF-010.1-2019 Operations Manual for EWG V08.pdf"/> - <echo message="get ${SISO-REF-010.1}"/> - <get src="${sisoBaseUrl}46173" - dest="${SISO-REF-010.1}" verbose="true"/> - --> + <echo message="get ${SISO-REF-010.1}"/> + <echo message="from ${sisoBaseUrl}47284"/> + <echo message="as ${SISO-REF-010}/${SISO-REF-010.1}"/> + <get src="${sisoBaseUrl}47284" + dest="${SISO-REF-010}" verbose="true"/> + <echo message="fix download filename"/> + <move file="${SISO-REF-010}/DigitalLibrary.aspx" tofile="${SISO-REF-010}/${SISO-REF-010.1}" overwrite="true" verbose="true"/> </target>