Skip to content
Snippets Groups Projects
Commit 9e329247 authored by Terry D. Norbraten's avatar Terry D. Norbraten
Browse files

[Terry N.] first pass at getting ESPDUs from binary to parse to XML

parent 32a6b62a
No related branches found
No related tags found
No related merge requests found
Showing
with 2521 additions and 718 deletions
...@@ -76,11 +76,28 @@ ...@@ -76,11 +76,28 @@
<xmlvalidate file="${rst.subset.xsd}" failonerror="false" warn="true" lenient="true"/> <xmlvalidate file="${rst.subset.xsd}" failonerror="false" warn="true" lenient="true"/>
<!--note that XSD schema validation using schemavalidate task requires special setup https://ant.apache.org/manual/Tasks/schemavalidate.html--> <!--note that XSD schema validation using schemavalidate task requires special setup https://ant.apache.org/manual/Tasks/schemavalidate.html-->
<echo message="schemavalidate original schema ${rst.subset.xsd}"/> <echo message="schemavalidate original schema ${rst.subset.xsd}"/>
<!-- DFDL schema set can be found in the org.apache.daffodil.daffodil-lib-3.4.0.jar under the package org.apache.daffodil.xsd -->
<schemavalidate file="${rst.subset.xsd}" failonerror="true" warn="true" lenient="false" fullchecking="false"> <schemavalidate file="${rst.subset.xsd}" failonerror="true" warn="true" lenient="false" fullchecking="false">
<schema namespace="http://www.w3.org/2001/XMLSchema" file="${attrib.dir}/org/apache/daffodil/xsd/XMLSchema_for_DFDL.xsd"/> <!--<schema namespace="http://www.w3.org/2001/XMLSchema" file="${attrib.dir}/org/apache/daffodil/xsd/XMLSchema_for_DFDL.xsd"/>-->
<!-- <classpath>
<fileset dir="${dfdl.lib.dir}">
<include name="**/*.jar"/>
</fileset>
</classpath>-->
<xmlcatalog>
<!-- <classpath>
<fileset dir="${dfdl.lib.dir}">
<include name="**/*.jar"/>
</fileset>
</classpath>-->
<catalogpath>
<pathelement path="${xml.catalog}"/>
<!--<fileset dir="${attrib.dir}" includes="XMLCatalog.xml"/>-->
</catalogpath>
</xmlcatalog>
</schemavalidate> </schemavalidate>
<echo message="... schemavalidate passed"/> <echo message="... schemavalidate passed"/>
<echo message="daffodil parse dis rst"/> <!-- <echo message="daffodil parse rstdis "/>
<echo message="... (note that apache daffodil warnings about dfdl:encodingErrorPolicy can be ignored)"/> <echo message="... (note that apache daffodil warnings about dfdl:encodingErrorPolicy can be ignored)"/>
<antcall target="parse.validate"/> <antcall target="parse.validate"/>
<echo message="============================================"/> <echo message="============================================"/>
...@@ -96,23 +113,34 @@ ...@@ -96,23 +113,34 @@
<echo message="============================================"/> <echo message="============================================"/>
<echo message="Check well-formed result for ${output.xml}"/> <echo message="Check well-formed result for ${output.xml}"/>
<xmlvalidate file="${output.xml}" failonerror="false" warn="true" lenient="true"/> <xmlvalidate file="${output.xml}" failonerror="false" warn="true" lenient="true"/>
<!--note that XSD schema validation using schemavalidate task requires special setup https://ant.apache.org/manual/Tasks/schemavalidate.html--> note that XSD schema validation using schemavalidate task requires special setup https://ant.apache.org/manual/Tasks/schemavalidate.html
<echo message="Check schema-valid result for ${output.xml} using original ${rst.subset.xsd}"/> <echo message="Check schema-valid result for ${output.xml} using original ${rst.subset.xsd}"/>
<!-- note failonerror="false" in order to reach follow-on TODO note failonerror="false" in order to reach follow-on TODO
TODO: Do we need the attrib noNamespaceFile? (tdn) --> TODO: Do we need the attrib noNamespaceFile? (tdn)
<schemavalidate file="${output.xml}" failonerror="false" warn="true" lenient="false" <schemavalidate file="${output.xml}" failonerror="false" warn="true" lenient="false"
disableDTD="true" fullchecking="true" noNamespaceFile="${rst.subset.xsd}"/> disableDTD="true" fullchecking="true" noNamespaceFile="${rst.subset.xsd}"/>
<echo message="TODO validation errors seem due to insufficient XML generation by Apache Daffodil"/> <echo message="TODO validation errors seem due to insufficient XML generation by Apache Daffodil"/>
<echo message="Suggested namespace declaration additions:"/> <echo message="Suggested namespace declaration additions:"/>
<echo message=' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'/> <echo message=' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'/>
<echo message=' xsi:noNamespaceSchemaLocation="${rst.subset.xsd}"'/> <echo message=' xsi:noNamespaceSchemaLocation="${rst.subset.xsd}"'/>-->
</target>
<target name="trace.parse.no.validate" depends="init">
<exec executable="${bin.dir}/daffodil" vmlauncher="false">
<arg value="-t"/>
<arg value="parse"/>
<arg line="-s ${rst.subset.xsd}"/>
<arg value="--nostream"/>
<arg line="-o ${output.xml}"/>
<arg value="${input.data.path}"/>
</exec>
</target> </target>
<target name="parse.no.validate" depends="init"> <target name="parse.no.validate" depends="init">
<exec executable="${bin.dir}/daffodil" vmlauncher="false"> <exec executable="${bin.dir}/daffodil" vmlauncher="false">
<arg value="parse"/> <arg value="parse"/>
<arg line="-s ${rst.subset.xsd}"/> <arg line="-s ${rst.subset.xsd}"/>
<arg value="--stream"/> <arg value="--stream"/> <!-- nostream good for debugging -->
<arg line="-o ${output.xml}"/> <arg line="-o ${output.xml}"/>
<arg value="${input.data.path}"/> <arg value="${input.data.path}"/>
</exec> </exec>
......
PDU Header
7, Protocol Version
1, Exercise ID
22, PDU Type
5, Protocol Family
0,0,0,0,0, Timestamp
80, Length
40, PDU Status
0, Padding
Originating ID
0, Site #
0, App. #
0, Ref. #
Receiving ID
0, Site #
0, App. #
0, Ref. #
0, Number of Fixed Datum Records
0, Number of Variable Datum Records (M)
Variable Datam i
0,0,0,0,0,0,0,0,0,0,0,1,0,0,-81,-46,0,0,1, Variable Datum ID
64, Variable Datum Length
83,105,109,117,108,97,116,105,111,110,32,116,105,109,101,115,116,101,112,32,100,117,114,97,116,105,111,110,32,49,46,48,32,115,101,99,111,110,100,115
Variable Datum Value
PDU Header
7, Protocol Version
1, Exercise ID
1, PDU Type
1, Protocol Family
0,0,0,0,0, Timestamp
-112, Length
40, PDU Status
0, Padding
Entity ID
0, Site #
1, App. #
0, Entity #
2, Force ID
0, Number of Variable Parameter Records
Entity Type
3, Entity Kind
1, Domain
0, Country
1, Category
2, Subcategory
0, Specific
-31, Extra
Alternate Entity Type
23, Entity Kind
2, Domain
1, Country
0, Category
0, Subcategory
0, Specific
0, Extra
Entity Linear Velocity
-31, x-component
0, y-component
0, z-component
Entity Location
0, X-component
0, Y-component
0, Z-component
Entity Orientation
0, Psi
0, Theta
0, Phi
Dead Reckoning Parameters
0, Dead Reckoning Algorithm
0, Other Parameters
0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0
File added
File added
File added
File added
File added
main.class=edu.nps.moves.dis7.examples.PduGenerator
main.class=edu.nps.moves.dis7.examples.PduGenerator
main.class=edu.nps.moves.dis7.examples.PduGenerator
...@@ -29,17 +29,25 @@ debug.test.modulepath=\ ...@@ -29,17 +29,25 @@ debug.test.modulepath=\
dist.archive.excludes= dist.archive.excludes=
# This directory is removed when the project is cleaned: # This directory is removed when the project is cleaned:
dist.dir=dist dist.dir=dist
dist.jar=${dist.dir}/dis.jar dist.jar=${dist.dir}/${application.title}.jar
dist.javadoc.dir=${dist.dir}/javadoc dist.javadoc.dir=${dist.dir}/javadoc
dist.jlink.dir=${dist.dir}/jlink dist.jlink.dir=${dist.dir}/jlink
dist.jlink.output=${dist.jlink.dir}/dis dist.jlink.output=${dist.jlink.dir}/dis
endorsed.classpath= endorsed.classpath=
excludes= excludes=
file.reference.commons-io-2.6.jar=lib/commons-io-2.6.jar
file.reference.guava-28.0-jre.jar=lib/guava-28.0-jre.jar
file.reference.opendis7-pdus-classes.jar=lib/opendis7-pdus-classes.jar
file.reference.opendis7-enumerations-classes.jar=lib/opendis7-enumerations-classes.jar
includes=** includes=**
jar.archive.disabled=${jnlp.enabled} jar.archive.disabled=${jnlp.enabled}
jar.compress=false jar.compress=false
jar.index=${jnlp.enabled} jar.index=${jnlp.enabled}
javac.classpath= javac.classpath=\
${file.reference.opendis7-pdus-classes.jar}:\
${file.reference.opendis7-enumerations-classes.jar}:\
${file.reference.commons-io-2.6.jar}:\
${file.reference.guava-28.0-jre.jar}
# Space-separated list of extra javac options # Space-separated list of extra javac options
javac.compilerargs= javac.compilerargs=
javac.deprecation=false javac.deprecation=false
...@@ -84,7 +92,7 @@ jnlp.signed=false ...@@ -84,7 +92,7 @@ jnlp.signed=false
jnlp.signing= jnlp.signing=
jnlp.signing.alias= jnlp.signing.alias=
jnlp.signing.keystore= jnlp.signing.keystore=
main.class= main.class=edu.nps.moves.dis7.utilities.stream.PduRecorderIEEE
# Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found. # 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= 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. # Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts.
...@@ -119,11 +127,15 @@ test.resources.dir=src/test/resources ...@@ -119,11 +127,15 @@ test.resources.dir=src/test/resources
test.src.dir=src/test/java test.src.dir=src/test/java
# Project specific resources # Project specific resources
bin.dir=../../bin dfdl.lib.dir=../../lib
#bin.dir=/Users/terry/javaapis/Apache Software Foundation (ASF)/apache-daffodil-3.5.0-bin/bin #bin.dir=../../bin
attrib.dir=../../lib bin.dir=../../../../Apache Software Foundation (ASF)/apache-daffodil-3.5.0-bin/bin
attrib.dir=../../attribution
xml.catalog=${attrib.dir}/XMLCatalog.xml
pkg.path=edu/nps/moves/xsd/rst/dis pkg.path=edu/nps/moves/xsd/rst/dis
rst.subset.xsd=${src.resources.dir}/${pkg.path}/DIS_7_2012.RichSemanticTrackSubset.dfdl.xsd #rst.subset.xsd=${src.resources.dir}/${pkg.path}/DIS_7_2012.RichSemanticTrackSubset-string.dfdl_xsd
input.data.name=PduCaptureLog rst.subset.xsd=${src.resources.dir}/${pkg.path}/DIS_7_2012.RichSemanticTrackSubset-binary.dfdl_xsd
#input.data.name=PduGenerator_ENCODING_PLAINTEXT_PduCaptureLog
input.data.name=PduGenerator_ENCODING_BINARY_PduCaptureLog
input.data.path=${test.resources.dir}/${pkg.path}/data/${input.data.name}.dislog input.data.path=${test.resources.dir}/${pkg.path}/data/${input.data.name}.dislog
output.xml=${data.file.name}.xml output.xml=${input.data.name}.xml
...@@ -3,14 +3,16 @@ Started 03 AUG 2023 ...@@ -3,14 +3,16 @@ Started 03 AUG 2023
To configure the NetBeans IDE to develop DFDL schemas, by following the To configure the NetBeans IDE to develop DFDL schemas, by following the
convention given for Eclipse: https://daffodil.apache.org/eclipse-configuration/ convention given for Eclipse: https://daffodil.apache.org/eclipse-configuration/
The NetBeans IDE will not let you create a new file extension containing a . The NetBeans IDE will not let you create a new file extension containing an
i.e. .dfdl.xsd, as Eclipse does, so, disregard that part. It's most important to extra . in the file extension, i.e. .dfdl.xsd, as Eclipse does, so, disregard
configure the User XML catalog as follows: that part. It's most important to just configure the User XML catalog as
follows:
Configure the UserXMLCatalog.xml file located at Configure the UserXMLCatalog.xml file located at
${DEFAULT_USERDIR_ROOT}/18/config/xml/ by placing this entry between the empty ${DEFAULT_USERDIR_ROOT}/18/config/xml/ by placing the below entry between the
catalog elements. Note: WIN machines will need a uri that begins like this: empty catalog elements. If not yet created, then select Tools -> DTDs and XML
file:///c:path/to/your/robodata/clone Schemas -> User Catalog -> Add local DTD or Schema. Note: WIN machines will need
a uri that begins like this: file:///c:path/to/your/robodata/clone
<public publicId="-//W3C//DTD XMLSCHEMA 200102//EN" uri="file:/Users/terry/javaapis/robodata/DFDL/attribution/org/apache/daffodil/xsd/XMLSchema.dtd"/> <public publicId="-//W3C//DTD XMLSCHEMA 200102//EN" uri="file:/Users/terry/javaapis/robodata/DFDL/attribution/org/apache/daffodil/xsd/XMLSchema.dtd"/>
<public publicId="datatypes" uri="file:/Users/terry/javaapis/robodata/DFDL/attribution/org/apache/daffodil/xsd/datatypes.dtd"/> <public publicId="datatypes" uri="file:/Users/terry/javaapis/robodata/DFDL/attribution/org/apache/daffodil/xsd/datatypes.dtd"/>
......
/**
* Copyright (c) 2008-2022, MOVES Institute, Naval Postgraduate School (NPS). All rights reserved.
* This work is provided under a BSD-style open-source license, see project
* <a href="https://savage.nps.edu/opendis7-java/license.html" target="_blank">license.html</a> and <a href="https://savage.nps.edu/opendis7-java/license.txt" target="_blank">license.txt</a>
*/
package edu.nps.moves.dis7.utilities;
import edu.nps.moves.dis7.pdus.Pdu;
import edu.nps.moves.dis7.utilities.stream.PduRecorder;
import edu.nps.moves.dis7.utilities.stream.PduRecorderIEEE;
/**
* DisChannel integrates multiple utility capabilities to handle most networking and entity-management tasks.
* Provides a simplified interface wrapping DisThreadedNetworkInterface, PduRecorderIEEE, and SimulationManager
* for programs connecting to OpenDis7 communications.
*
* Based on the original <a href="https://github.com/open-dis/opendis7-java" target="_blank">edu.nps.moves.dis7.utilities.DisChannel</a>
* Modified to invoke the PduRecorderIEEE which records PLAINTEXT PDUs without headers/footers/comments
*
* <br>
TODO future work will confirm that multiple different DisChannelIEEE connections can be used simultaneously by a parent program.
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/specifications/README.md">MV3500 Distributed Simulation Fundamentals, Specification Documents, IEEE and SISO</a>
* @see <a href="https://ieeexplore.ieee.org/document/6387564">1278.1-2012. IEEE Standard for Distributed Interactive Simulation (DIS) - Application Protocols</a>
* @author brutzman
* @author <a href="mailto:tdnorbra@nps.edu?subject=edu.nps.moves.dis7.utilities.DisChannelIEEE">Terry D. Norbraten</a>
*/
public class DisChannelIEEE extends DisChannel
{
private static String PDU_ENCODING;
/** Base constructor */
public DisChannelIEEE()
{
super();
}
/** Constructor with new descriptor
* @param initialDescriptor descriptor for this instance
*/
public DisChannelIEEE(String initialDescriptor)
{
super(initialDescriptor);
}
/** Constructor with new verboseness
* @param verbosenessDisNetworkInterface whether channel is initially verbose
* @param verbosenessPduRecorder whether PduRecorder is initially verbose
*/
public DisChannelIEEE(boolean verbosenessDisNetworkInterface, boolean verbosenessPduRecorder)
{
super(verbosenessDisNetworkInterface, verbosenessPduRecorder);
}
/** Constructor with new descriptor, verboseness
* @param initialDescriptor descriptor for this instance
* @param verbosenessDisNetworkInterface whether channel is initially verbose
* @param verbosenessPduRecorder whether PduRecorder is initially verbose
*/
public DisChannelIEEE(String initialDescriptor, boolean verbosenessDisNetworkInterface, boolean verbosenessPduRecorder)
{
super(initialDescriptor, verbosenessDisNetworkInterface, verbosenessPduRecorder);
}
@Override
public synchronized void setUpNetworkInterface()
{
if (disNetworkInterface != null)
{
printlnTRACE("*** Warning: setUpNetworkInterface() has already created disNetworkInterface, second invocation ignored");
return;
}
disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort());
getDisNetworkInterface().setDescriptor(descriptor);
getDisNetworkInterface().setVerbose(isVerboseDisNetworkInterface());
if (isVerbosePduRecorder())
printlnTRACE("Network confirmation:" + " address=" + getDisNetworkInterface().getAddress() + // disNetworkInterface.getMulticastGroup() +
" port=" + getDisNetworkInterface().getPort()); // + disNetworkInterface.getDisPort());
pduListener = (Pdu newPdu) -> {
receivedPdu = newPdu;
}; /** Callback handler for listener */
getDisNetworkInterface().addListener(pduListener);
String pduLogOutputDirectory = DEFAULT_PDULOG_OUTPUT_DIRECTORY;
printlnTRACE("Beginning pdu save to directory " + pduLogOutputDirectory);
pduRecorder = new PduRecorderIEEE(pduLogOutputDirectory, getNetworkAddress(), getNetworkPort()); // assumes save
pduRecorder.setEncodingPduLog(getPDU_ENCODING());
// Here is where we need plain text PDU output in CSV with no headers/footers/comments, etc
if (getPDU_ENCODING().equals(PduRecorder.ENCODING_PLAINTEXT))
pduRecorder.setIncludeHeaders(false); // was set true in above method call
pduRecorder.setLogFileName(descriptor + "_" + getPDU_ENCODING() + "_" + PduRecorder.DEFAULT_FILE_NAME);
pduRecorder.setVerbose(isVerboseDisNetworkInterface()); // either sending, receiving or both
pduRecorder.start(); // begin running
}
/**
* @return the PDU_ENCODING
*/
public static String getPDU_ENCODING() {
return PDU_ENCODING;
}
/**
* @param PDU_ENCODING the PDU_ENCODING to set
*/
public static void setPDU_ENCODING(String PDU_ENCODING) {
DisChannelIEEE.PDU_ENCODING = PDU_ENCODING;
}
} // end class DisChannelIEEE
package edu.nps.moves.dis7.utilities.stream;
import edu.nps.moves.dis7.enumerations.DisPduType;
import edu.nps.moves.dis7.pdus.Pdu;
import edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
/** Utility to save PDUs received over the network to disk, greatly simplifying the capture of DIS streams by applications.
*
* Example <code>main()</code> self-test response shown in log file, example results also included.
* @see <a href="https://github.com/open-dis/open-dis7-java/blob/master/src/edu/nps/moves/dis7/utilities/stream/PduRecorderSelfTestLog.txt">https://github.com/open-dis/open-dis7-java/blob/master/src/edu/nps/moves/dis7/utilities/stream/PduRecorderSelfTestLog.txt</a>
* @see <a href="https://github.com/open-dis/open-dis7-java/blob/master/src/edu/nps/moves/dis7/utilities/stream/PduRecorderSelfTestENCODING_BASE64_PduCaptureLog.dislog">https://github.com/open-dis/open-dis7-java/blob/master/src/edu/nps/moves/dis7/utilities/stream/PduRecorderSelfTestENCODING_BASE64_PduCaptureLog.dislog</a>
* @see <a href="https://github.com/open-dis/open-dis7-java/blob/master/src/edu/nps/moves/dis7/utilities/stream/PduRecorderSelfTestENCODING_BINARY_PduCaptureLog.dislog">https://github.com/open-dis/open-dis7-java/blob/master/src/edu/nps/moves/dis7/utilities/stream/PduRecorderSelfTestENCODING_BINARY_PduCaptureLog.dislog</a>
* @see <a href="https://github.com/open-dis/open-dis7-java/blob/master/src/edu/nps/moves/dis7/utilities/stream/PduRecorderSelfTestENCODING_PLAINTEXT_PduCaptureLog.dislog">https://github.com/open-dis/open-dis7-java/blob/master/src/edu/nps/moves/dis7/utilities/stream/PduRecorderSelfTestENCODING_PLAINTEXT_PduCaptureLog.dislog</a>
*
* Based on the original <a href="https://github.com/open-dis/opendis7-java" target="_blank">edu.nps.moves.dis7.utilities.stream.PduRecorder</a>
* Modified to record PLAINTEXT PDUs without headers/footers/comments
*
* @author Don Brutzman, brutzman@nps.edu
* @author Mike Bailey, jmbailey@nps.edu
* @author <a href="mailto:tdnorbra@nps.edu?subject=edu.nps.moves.dis7.utilities.stream.PduRecorderIEEE">Terry D. Norbraten</a>
*/
public class PduRecorderIEEE extends PduRecorder // implements PduReceiver
{
/**
* Default constructor that uses default values for output directory, DIS address and port.
* Each instance must invoke start() to begin operations, pause() to suspend operations,
* resume() to continue operations, and stop() to terminate operations.
*/
public PduRecorderIEEE()
{
this(OUTPUT_DIRECTORY_DEFAULT);
}
/**
* Constructor to let the use specify an output directory.
* Uses default values for multicast address and port.
* Each instance must invoke start() to begin operations, pause() to suspend operations,
* resume() to continue operations, and stop() to terminate operations.
*
* @param initialOutputDirectory the directory to write log files to
*/
public PduRecorderIEEE(String initialOutputDirectory)
{
this(initialOutputDirectory, DEFAULT_DIS_ADDRESS, DEFAULT_DIS_PORT);
}
/** Constructor to let the user specify all required parameters.
* Each instance must invoke start() to begin operations, pause() to suspend operations,
* resume() to continue operations, and stop() to terminate operations..
*
* @param initialOutputDirectory local path for directory where the log files are written
* @param initialAddress multicast group address to receive data from (TODO allow unicast UDP)
* @param initialPort UDP port to listen for data
*/
public PduRecorderIEEE(String initialOutputDirectory, String initialAddress, int initialPort)
{
super(initialOutputDirectory, initialAddress, initialPort);
setIncludeHeaders(false);
setReadableTimeStamp(false);
setDescriptor(getClass().getSimpleName());
}
/** receivePdu from DIS data stream, invoked via callback from DisThreadedNetworkInterface.RawPduListener
* @param newBuffer byte array for receiving data
* @param newLength length of byte array
*/
@Override
public void receivePdu(byte[] newBuffer, int newLength)
{
if(!isRunning())
return; // thread operations no longer in progress, ignore this received PDU
byte[] byteBufferSized = Arrays.copyOf(newBuffer, newLength);
switch (encodingPduLog)
{
case ENCODING_BINARY:
// diagnostics can go here, TODO is any processing needed?
break;
case ENCODING_BASE64:
sb.append(base64Encoder.encodeToString(byteBufferSized));
break;
case ENCODING_PLAINTEXT:
// No timestamp in the beginning, just pure PDU contents
// PDU contents, remove square brackets to end up with pure CSV
sb.append(Arrays.toString(byteBufferSized).replace(" ", "").replace("[","").replace("]",""));
break;
default:
if (ENCODING_OPTIONS_LIST.contains(encodingPduLog))
System.err.println ("Encoding " + encodingPduLog + " not supported");
else
System.err.println ("Encoding " + encodingPduLog + " not recognized");
break;
}
try
{
if (encodingPduLog.equals(ENCODING_BINARY))
{
// https://stackoverflow.com/questions/4931854/converting-char-array-into-byte-array-and-back-again
Charset charset = Charset.forName("ISO-8859-1"); // Must be this to get the proper encoding to DFDL
// Charset charset = Charset.forName("UTF_8");
// Charset charset = Charset.forName("US-ASCII");
CharBuffer charBufferSized = charset.decode(ByteBuffer.wrap(byteBufferSized));
logFileWriter.write(charBufferSized.array());
}
else
{
logFileWriter.write(sb.toString());
((PrintWriter)logFileWriter).println();
}
}
catch (IOException ex)
{
throw new RuntimeException("Fatal exception writing DIS log file in " + getDescriptor() + " thread, encodingPduLog=" + encodingPduLog + ": " + ex);
}
pduCount = pduCount + 1;
// if (false) // debug
// System.out.println(TRACE_PREFIX + " + getDescriptor() + ": pduCount="+ pduCount);
sb.setLength(0);
}
/**
* Entry point invocation to facilitate developmental testing, runs selfTest() method.
*
* @param args none supported, TODO offer path/filename
*/
public static void main(String[] args)
{
PduRecorder pduRecorder = new PduRecorderIEEE(); // instantiates an instance object of this class,
pduRecorder.selfTest(args); // and tests it. Results shown in .dislog files.
}
/** This selfTest() method saves PDU output logs to assigned directory using all supported encodings.
* Further checking can be accomplished by separately Invoking the edu.nps.moves.dis7.examples.PduReaderPlayer
* which will playback all logs written to that log directory.
*
* @param args none supported, TODO offer path/filename
*/
@Override
public synchronized void selfTest(String[] args)
{
System.out.println(getDescriptor() + " main() performs self-test by sending full set of PDUs");
PduRecorder pduRecorder;
DisThreadedNetworkInterface disNetworkInterface;
DisPduType allPDUTypesArray[] = DisPduType.values();
System.out.println(getDescriptor() + " allPDUTypesArray created, length=" + allPDUTypesArray.length + " ...");
System.out.flush(); // ensure all output sent
for (String currentEncoding : ENCODING_OPTIONS_LIST)
{
pduRecorder = new PduRecorderIEEE(); // default address, port, output directory path
System.out.println("=================================================");
System.out.println("Test " + getDescriptor() + " encoding " + currentEncoding);
pduRecorder.setEncodingPduLog(currentEncoding);
// Here is where we need plain text PDU output in CSV with no headers/footers/comments, etc
if (pduRecorder.getEncodingPduLog().equals(ENCODING_PLAINTEXT))
pduRecorder.setIncludeHeaders(false); // was set true in above method call
pduRecorder.setDescriptor(getDescriptor() + ".selfTest " + currentEncoding);
// pduRecorder.setPort(1); // option to avoid listening to other PDU streams during self test
pduRecorder.setLogFileName(getDescriptor() + ".selfTest" + "_" + currentEncoding + "_" + DEFAULT_FILE_NAME);
pduRecorder.start();
disNetworkInterface = pduRecorder.getDisThreadedNetworkInterface(); // must reinitialize after each begin
System.out.println(pduRecorder.getDescriptor() + " pduRecorder started... isRunning()=" + pduRecorder.isRunning());
for (int index=0; index < allPDUTypesArray.length; index++)
{
DisPduType pduTypeValue = allPDUTypesArray[index];
if (pduTypeValue != DisPduType.OTHER)
{
try {
// These are empty PDUs, no boilerplate data marshalled
Pdu nextPdu = pduFactory.createPdu(allPDUTypesArray[index]);
nextPdu.setTimestamp(index * 10); // seconds
nextPdu.setLength(nextPdu.getMarshalledSize());
// nextPdu.getTimestamp(); // debug
disNetworkInterface.send(nextPdu);
// https://stackoverflow.com/questions/10663920/calling-thread-sleep-from-synchronized-context-in-java
// https://stackoverflow.com/questions/1036754/difference-between-wait-vs-sleep-in-java
wait (100L); // let send/receive threads and streams catch up // TODO consider wait() instead of sleep()
}
catch (InterruptedException ex) {
System.err.println("Exception sending Pdu " + pduTypeValue + ": " + ex.getLocalizedMessage());
}
}
else
{
System.err.println("Found pduTypeValue=DisPduType.OTHER=" + pduTypeValue);
}
}
System.out.flush();
System.err.flush(); // ensure all output sent
pduRecorder.stop();
System.out.println(pduRecorder.getDescriptor() + " pduRecorder complete... isRunning()=" + pduRecorder.isRunning());
}
// end of loop ENCODING_OPTIONS_LIST
System.out.println("=================================================");
}
} // end class PduRecorderIEEE
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2021 Owl Cyber Defense. All rights reserved.
Developed by: Owl Cyber Defense
http://www.owlcyberdefense.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
3. Neither the names of Owl Cyber Defense, nor the names of its contributors
may be used to endorse or promote products derived from this Software
without specific prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
-->
<!--
Basic byte-oriented binary data. This is a standard set of
conventions useful for describing things like IP packets.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions"
xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
xmlns:dafint="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:int"
xmlns:b="urn:basicBinary"
xmlns:tns="urn:basicBinary"
targetNamespace="urn:basicBinary">
<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:defineFormat name="basicByteBinary">
<dfdl:format ref="tns:GeneralFormat"
alignmentUnits="bits"
documentFinalTerminatorCanBeMissing="yes"
lengthUnits="bits"
representation="binary"/>
</dfdl:defineFormat>
<dfdl:format ref="b:basicByteBinary"/>
</xs:appinfo>
</xs:annotation>
<xs:simpleType name="bit" dfdl:lengthKind="explicit">
<xs:restriction base="xs:unsignedInt"/>
</xs:simpleType>
<xs:simpleType name="enum8" dfdl:lengthKind="explicit" dfdl:length="8">
<xs:restriction base="xs:unsignedInt"/>
</xs:simpleType>
<xs:simpleType name="ubyte" dfdl:lengthKind="explicit" dfdl:length="8">
<xs:restriction base="xs:unsignedInt"/>
</xs:simpleType>
<xs:simpleType name="uint16" dfdl:lengthKind="explicit" dfdl:length="16">
<xs:restriction base="xs:unsignedInt"/>
</xs:simpleType>
<xs:simpleType name="uint32" dfdl:lengthKind="explicit" dfdl:length="32">
<xs:restriction base="xs:unsignedInt"/>
</xs:simpleType>
<xs:simpleType name="int32" dfdl:lengthKind="explicit" dfdl:length="4"
dfdl:lengthUnits="bytes">
<xs:restriction base="xs:int"/>
</xs:simpleType>
<xs:simpleType name="enum120" dfdl:lengthKind="explicit" dfdl:length="120">
<xs:restriction base="xs:nonNegativeInteger"/>
</xs:simpleType>
</xs:schema>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment