diff --git a/src/edu/nps/moves/dis7/utilities/stream/PduRecorder.java b/src/edu/nps/moves/dis7/utilities/stream/PduRecorder.java index 030d845dfaf70c4931dd74c79d0d6fff10ae7a58..571d464f6d4e20ce852c70e75ba8681916db28f6 100644 --- a/src/edu/nps/moves/dis7/utilities/stream/PduRecorder.java +++ b/src/edu/nps/moves/dis7/utilities/stream/PduRecorder.java @@ -36,339 +36,354 @@ public class PduRecorder implements PduReceiver * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */ public static int DEFAULT_DIS_PORT = DisThreadedNetworkInterface.DEFAULT_DIS_PORT; - private String disAddress = DEFAULT_DIS_ADDRESS; - private int disPort = DEFAULT_DIS_PORT; - - /** Character sentinel indicating remainder of line is a comment */ - public static final String COMMENT_MARKER = "#"; - - static final String OUTPUT_DIRECTORY_DEFAULT = "./pduLog"; - String outputDirectory = OUTPUT_DIRECTORY_DEFAULT; - Path outputDirectoryPath; - static String DEFAULT_FILE_PREFIX = "PduCaptureLog"; - static String DISLOG_FILE_EXTENSION = ".dislog"; - - static final String START_COMMENT_MARKER = COMMENT_MARKER + " Start, "; - static final String FINISH_COMMENT_MARKER = COMMENT_MARKER + " Finish, "; - static final String ENCODING_BASE64 = "ENCODING_BASE64"; - static final String ENCODING_PLAINTEXT = "ENCODING_PLAINTEXT"; - static final String ENCODING_BINARY = "ENCODING_BINARY"; // TODO likely requires different code path - static final String ENCODING_XML = "ENCODING_XML"; // TODO, repeat Open-DIS version 4 effort - static final String ENCODING_EXI = "ENCODING_EXI"; // TODO, use Exificient or Nagasena libraries - static final String ENCODING_JSON = "ENCODING_JSON"; // TODO, repeat Open-DIS version 4 effort - static final String ENCODING_MAK_DATA_LOGGER = "ENCODING_MAK_DATA_LOGGER"; // verbose pretty-print. perhaps output only (MAK format itself is binary) - static final String ENCODING_WIRESHARK_DATA_LOGGER = "ENCODING_WIRESHARK_DATA_LOGGER"; // - static final String ENCODING_CDIS = "ENCODING_CDIS"; // future work based on new SISO standard + private String disAddress = DEFAULT_DIS_ADDRESS; + private int disPort = DEFAULT_DIS_PORT; - private static String pduLogEncoding = ENCODING_PLAINTEXT; // TODO use Java enumerations, generalize/share across library - - private String TRACE_PREFIX = ("[pduRecorder " + getDescriptor()).trim() + "] "; - private String descriptor = new String(); + private boolean verbose = true; + private boolean verboseReceipt = true; + private boolean verboseSending = true; + private boolean verboseIncludesTimestamp = false; + + /** Character sentinel indicating remainder of line is a comment */ + public static final String COMMENT_MARKER = "#"; - private Writer logFileWriter; - private File logFile; - private DisThreadedNetworkInterface disThreadedNetworkInterface; - private DisThreadedNetworkInterface.RawPduListener disRawPduListener; - - private Long startNanoTime = null; - private final StringBuilder sb = new StringBuilder(); - private final Base64.Encoder base64Encoder = Base64.getEncoder(); - private static int port = DisThreadedNetworkInterface.DEFAULT_DIS_PORT; // self-test via port 1 when main() invoked - private final int pduCount = 0; // debug - private boolean headerWritten = false; - private boolean running = true; // starts recording by default - - /** - * 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. - * @throws IOException if something goes wrong during instantiation - */ - public PduRecorder() throws IOException - { - this (OUTPUT_DIRECTORY_DEFAULT, DEFAULT_DIS_ADDRESS, DEFAULT_DIS_PORT); - } - - /** - * 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 - * @throws IOException if something goes wrong during instantiation - */ - public PduRecorder(String initialOutputDirectory) throws IOException - { - this(initialOutputDirectory, DEFAULT_DIS_ADDRESS, DEFAULT_DIS_PORT); - } + static final String OUTPUT_DIRECTORY_DEFAULT = "./pduLog"; + String outputDirectory = OUTPUT_DIRECTORY_DEFAULT; + Path outputDirectoryPath; + static String DEFAULT_FILE_PREFIX = "PduCaptureLog"; + static String DISLOG_FILE_EXTENSION = ".dislog"; + + static final String START_COMMENT_MARKER = COMMENT_MARKER + " Start, "; + static final String FINISH_COMMENT_MARKER = COMMENT_MARKER + " Finish, "; + static final String ENCODING_BASE64 = "ENCODING_BASE64"; + static final String ENCODING_PLAINTEXT = "ENCODING_PLAINTEXT"; + static final String ENCODING_BINARY = "ENCODING_BINARY"; // TODO likely requires different code path + static final String ENCODING_XML = "ENCODING_XML"; // TODO, repeat Open-DIS version 4 effort + static final String ENCODING_EXI = "ENCODING_EXI"; // TODO, use Exificient or Nagasena libraries + static final String ENCODING_JSON = "ENCODING_JSON"; // TODO, repeat Open-DIS version 4 effort + static final String ENCODING_MAK_DATA_LOGGER = "ENCODING_MAK_DATA_LOGGER"; // verbose pretty-print. perhaps output only (MAK format itself is binary) + static final String ENCODING_WIRESHARK_DATA_LOGGER = "ENCODING_WIRESHARK_DATA_LOGGER"; // + static final String ENCODING_CDIS = "ENCODING_CDIS"; // future work based on new SISO standard + + private static String pduLogEncoding = ENCODING_PLAINTEXT; // TODO use Java enumerations, generalize/share across library + + private String TRACE_PREFIX = ("[pduRecorder " + getDescriptor()).trim() + "] "; + private String descriptor = new String(); + + private Writer logFileWriter; + private File logFile; + private DisThreadedNetworkInterface disThreadedNetworkInterface; + private DisThreadedNetworkInterface.RawPduListener disRawPduListener; + + private Long startNanoTime = null; + private final StringBuilder sb = new StringBuilder(); + private final Base64.Encoder base64Encoder = Base64.getEncoder(); + private final int pduCount = 0; // debug + private boolean headerWritten = false; + private boolean running = true; // starts recording by default - /** 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 - */ - @SuppressWarnings("Convert2Lambda") - public PduRecorder(String initialOutputDirectory, String initialAddress, int initialPort) - { - try { - outputDirectoryPath = new File(initialOutputDirectory).toPath(); - this.descriptor = "PduRecorder"; // default - this.disAddress = initialAddress; - this.disPort = initialPort; - logFile = createUniquePduLogFile(outputDirectoryPath, DEFAULT_FILE_PREFIX + DISLOG_FILE_EXTENSION ); - logFileWriter = new PrintWriter(new BufferedWriter(new FileWriter(logFile))); - } - catch (IOException ex) + /** + * 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. + * @throws IOException if something goes wrong during instantiation + */ + public PduRecorder() throws IOException { - System.err.println("Exception when creating log file in directory=" + initialOutputDirectory + "\n" + - " " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage()); + this (OUTPUT_DIRECTORY_DEFAULT, DEFAULT_DIS_ADDRESS, DEFAULT_DIS_PORT); } - } - + /** - * TODO change this to enumeration type for strictness - * - * @return the pduLogEncoding + * 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 + * @throws IOException if something goes wrong during instantiation */ - public static String getPduLogEncoding() + public PduRecorder(String initialOutputDirectory) throws IOException { - return pduLogEncoding; + this(initialOutputDirectory, DEFAULT_DIS_ADDRESS, DEFAULT_DIS_PORT); } - /** - * @param newPduLogEncoding the pduLogEncoding to set + /** 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 static void setPduLogEncoding(String newPduLogEncoding) { - pduLogEncoding = newPduLogEncoding; + @SuppressWarnings("Convert2Lambda") + public PduRecorder(String initialOutputDirectory, String initialAddress, int initialPort) + { + try { + outputDirectoryPath = new File(initialOutputDirectory).toPath(); + this.descriptor = "PduRecorder"; // default + this.disAddress = initialAddress; + this.disPort = initialPort; + logFile = createUniquePduLogFile(outputDirectoryPath, DEFAULT_FILE_PREFIX + DISLOG_FILE_EXTENSION ); + logFileWriter = new PrintWriter(new BufferedWriter(new FileWriter(logFile))); + } + catch (IOException ex) + { + System.err.println("Exception when creating log file in directory=" + initialOutputDirectory + "\n" + + " " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage()); + } } - /** Resume instance operation - * @see start() - * @see stop() - * @see pause() */ - public void resume() - { - if (disThreadedNetworkInterface == null) + /** + * TODO change this to enumeration type for strictness + * + * @return the pduLogEncoding + */ + public static String getPduLogEncoding() + { + return pduLogEncoding; + } + + /** + * @param newPduLogEncoding the pduLogEncoding to set + */ + public static void setPduLogEncoding(String newPduLogEncoding) { + pduLogEncoding = newPduLogEncoding; + } + + /** Resume instance operation + * @see start() + * @see stop() + * @see pause() */ + public void resume() { - System.out.println("** Warning, PduRecorder resume() failed to find running disThreadedNetworkInterface, repeating start()"); - start(); // start me up + if (disThreadedNetworkInterface == null) + { + System.out.println("** Warning, PduRecorder resume() failed to find running disThreadedNetworkInterface, repeating start()"); + start(); // start me up + } + else running = true; } - else running = true; - } - /** Start instance operation - * @see stop() - * @see pause() - * @see resume() - */ - public void start() - { - if (disThreadedNetworkInterface == null) + /** Start instance operation + * @see stop() + * @see pause() + * @see resume() + */ + public void start() { - disThreadedNetworkInterface = new DisThreadedNetworkInterface(getAddress(), getPort()); - disThreadedNetworkInterface.setDescriptor (getDescriptor()); // pass it along - - disRawPduListener = new DisThreadedNetworkInterface.RawPduListener() { - @Override - public void incomingPdu(DisThreadedNetworkInterface.ByteArrayBufferAndLength bAndL) { - receivePdu(bAndL.bufferByteArray, bAndL.length); - } - }; - disThreadedNetworkInterface.addRawListener(disRawPduListener); - System.out.println("[" + (getClass().getSimpleName() + " " + getDescriptor()).trim() + "] listening to IP address " + getAddress() + " on port " + getPort()); + if (disThreadedNetworkInterface == null) + { + disThreadedNetworkInterface = new DisThreadedNetworkInterface(getAddress(), getPort()); + disThreadedNetworkInterface.setDescriptor (getDescriptor()); // pass it along + disThreadedNetworkInterface.setVerbose(verbose); + + disRawPduListener = new DisThreadedNetworkInterface.RawPduListener() { + @Override + public void incomingPdu(DisThreadedNetworkInterface.ByteArrayBufferAndLength bAndL) { + receivePdu(bAndL.bufferByteArray, bAndL.length); + } + }; + disThreadedNetworkInterface.addRawListener(disRawPduListener); + System.out.println("[" + (getClass().getSimpleName() + " " + getDescriptor()).trim() + "] listening to IP address " + getAddress() + " on port " + getPort()); + } + running = true; } - running = true; - } - /** Pause operation of this instance - * @see start() - * @see stop() - * @see resume() - */ - public void pause() - { - running = false; - } - /** End operation of this instance, removing interfaces - * @return recorder logFile - * @see start() - * @see pause() - * @see resume() */ - public File stop() - { - running = false; - if (disThreadedNetworkInterface != null) + /** Pause operation of this instance + * @see start() + * @see stop() + * @see resume() + */ + public void pause() { - disThreadedNetworkInterface.removeRawListener(disRawPduListener); - disThreadedNetworkInterface.finishOperations(); + running = false; } + /** End operation of this instance, removing interfaces + * @return recorder logFile + * @see start() + * @see pause() + * @see resume() */ + public File stop() + { + running = false; + if (disThreadedNetworkInterface != null) + { + disThreadedNetworkInterface.removeRawListener(disRawPduListener); + disThreadedNetworkInterface.finishOperations(); + } - writeFooter(); - try { - System.out.println(); - System.out.println("Closing recorder log file: " + logFile.getCanonicalPath()); - logFileWriter.close(); // a flush occurs first during a close - } - catch (IOException ex) { - Logger.getLogger(PduRecorder.class.getName()).log(Level.SEVERE, null, ex); + writeFooter(); + try { + System.out.println(); + System.out.println("Closing recorder log file: " + logFile.getCanonicalPath()); + logFileWriter.close(); // a flush occurs first during a close + } + catch (IOException ex) { + Logger.getLogger(PduRecorder.class.getName()).log(Level.SEVERE, null, ex); + } + return logFile; } - return logFile; - } - - byte[] oldBuffer; - - /** receivePdu from DIS data stream - * @param newBuffer byte array for receiving data - * @param newLength length of byte array - */ - @Override - public void receivePdu(byte[] newBuffer, int newLength) - { - if (java.util.Arrays.equals(newBuffer, oldBuffer)) - System.err.println ("PduRecorder warning: PDU newBuffer equals PDU oldBuffer"); // debug - - if(!isRunning()) - return; - - long packetRcvNanoTime = System.nanoTime(); - if (startNanoTime == null) - startNanoTime = packetRcvNanoTime; - byte[] timeByteArray = Longs.toByteArray(packetRcvNanoTime - startNanoTime); - //System.out.println("wrote time "+(packetRcvNanoTime - startNanoTime)); + byte[] oldBuffer; - byte[] buffsized = Arrays.copyOf(newBuffer, newLength); - DisPduType pduType; - - switch (pduLogEncoding) + /** receivePdu from DIS data stream + * @param newBuffer byte array for receiving data + * @param newLength length of byte array + */ + @Override + public void receivePdu(byte[] newBuffer, int newLength) { - case ENCODING_BASE64: - sb.append(base64Encoder.encodeToString(timeByteArray)); - sb.append(','); - sb.append(base64Encoder.encodeToString(buffsized)); - break; - - case ENCODING_PLAINTEXT: - // by Tobias Brennenstuhl SPring 2020 - sb.append(Arrays.toString(timeByteArray).replace(" ", "")); - sb.append(','); - sb.append(Arrays.toString(buffsized).replace(" ", "")); - sb.append(" # "); - pduType = DisPduType.getEnumForValue(Byte.toUnsignedInt(buffsized[2])); // 3rd byte - sb.append(pduType); - break; - - default: - System.err.println ("Encoding " + pduLogEncoding + " not recognized or supported"); - } - if (!headerWritten) { - writeHeader(); - headerWritten = true; - } - try { - logFileWriter.write(sb.toString()); - ((PrintWriter)logFileWriter).println(); - } - catch (IOException ex) { - throw new RuntimeException("Fatal exception writing DIS log file in PduRecorder thread: " + ex); + if (java.util.Arrays.equals(newBuffer, oldBuffer)) + System.err.println ("PduRecorder warning: PDU newBuffer equals PDU oldBuffer"); // debug + + if(!isRunning()) + return; + + long packetRcvNanoTime = System.nanoTime(); + if (startNanoTime == null) + startNanoTime = packetRcvNanoTime; + + byte[] timeByteArray = Longs.toByteArray(packetRcvNanoTime - startNanoTime); + //System.out.println("wrote time "+(packetRcvNanoTime - startNanoTime)); + + byte[] buffsized = Arrays.copyOf(newBuffer, newLength); + DisPduType pduType; + + switch (pduLogEncoding) + { + case ENCODING_BASE64: + sb.append(base64Encoder.encodeToString(timeByteArray)); + sb.append(','); + sb.append(base64Encoder.encodeToString(buffsized)); + break; + + case ENCODING_PLAINTEXT: + // by Tobias Brennenstuhl SPring 2020 + sb.append(Arrays.toString(timeByteArray).replace(" ", "")); + sb.append(','); + sb.append(Arrays.toString(buffsized).replace(" ", "")); + sb.append(" # "); + pduType = DisPduType.getEnumForValue(Byte.toUnsignedInt(buffsized[2])); // 3rd byte + sb.append(pduType); + break; + + default: + System.err.println ("Encoding " + pduLogEncoding + " not recognized or supported"); + } + if (!headerWritten) { + writeHeader(); + headerWritten = true; + } + try { + logFileWriter.write(sb.toString()); + ((PrintWriter)logFileWriter).println(); + } + catch (IOException ex) { + throw new RuntimeException("Fatal exception writing DIS log file in PduRecorder thread: " + ex); + } + //System.out.println("Recorder: "+ ++pduCount); + + sb.setLength(0); } - //System.out.println("Recorder: "+ ++pduCount); - sb.setLength(0); - } - - /** Retrieve the path to the log file - * - * @return the path to the log file - */ - public String getLogFilePath() - { - return logFile.getAbsolutePath(); - } - - /** - * @return an instance of this DisThreadedNetworkInterface + /** Retrieve the path to the log file + * + * @return the path to the log file */ - public DisThreadedNetworkInterface getDisThreadedNetworkInterface() { - return disThreadedNetworkInterface; + public String getLogFilePath() + { + return logFile.getAbsolutePath(); } - - private void writeHeader() - { - String timeStamp = getTimeStamp(); - try - { - logFileWriter.write(START_COMMENT_MARKER + pduLogEncoding + ", " + timeStamp + ", DIS capture file, " + logFile.getPath()); - ((PrintWriter) logFileWriter).println(); - } - catch (IOException ex) - { - Logger.getLogger(PduRecorder.class.getName()).log(Level.SEVERE, null, ex); + /** + * Deprecated, use getDisThreadedNetworkInterface() instead + * @see getDisThreadedNetworkInterface() + * @return an instance of this DisThreadedNetworkInterface + */ + @Deprecated + public DisThreadedNetworkInterface getDisThreadedNetIF() { + return getDisThreadedNetworkInterface(); } - } - private void writeFooter() - { - String timeStamp = getTimeStamp(); - - try - { - logFileWriter.write(FINISH_COMMENT_MARKER + pduLogEncoding + ", " + timeStamp + ", DIS capture file, " + logFile.getPath()); - ((PrintWriter) logFileWriter).println(); - } - catch (IOException ex) - { - Logger.getLogger(PduRecorder.class.getName()).log(Level.SEVERE, null, ex); + /** + * @return an instance of this DisThreadedNetworkInterface + */ + public DisThreadedNetworkInterface getDisThreadedNetworkInterface() { + return disThreadedNetworkInterface; } - } - - private String getTimeStamp() { - // https://stackoverflow.com/questions/5175728/how-to-get-the-current-date-time-in-java - return new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime()); - } - /** - * Rotates through file names so that no present file get overwritten. - * - * @param outputDir the directory to place the log file - * @param filename the name of the file w/ extension - * @return a File reference to the log file - * @throws IOException if something goes awry - */ - private File createUniquePduLogFile(Path outputDir, String filename) throws IOException - { - String baseName = FilenameUtils.getBaseName(filename); - String extension = FilenameUtils.getExtension(filename); - - Integer fileCounter = null; - File newFile; - boolean fileExists; - outputDir.toFile().mkdirs(); - do { - String nextFileName = baseName + (fileCounter == null ? "" : fileCounter) + "." + extension; - newFile = new File(outputDir.toFile(), nextFileName); - fileExists = newFile.exists(); - if (fileCounter == null) - fileCounter = 1; - else - fileCounter++; - } while (fileExists); - - if (newFile.createNewFile()) + private void writeHeader() { - System.out.println("Recorder log file open: " + newFile.getCanonicalPath()); + String timeStamp = getTimeStamp(); + + try + { + logFileWriter.write(START_COMMENT_MARKER + pduLogEncoding + ", " + timeStamp + ", DIS capture file, " + logFile.getPath()); + ((PrintWriter) logFileWriter).println(); + } + catch (IOException ex) + { + Logger.getLogger(PduRecorder.class.getName()).log(Level.SEVERE, null, ex); + } } - else + + private void writeFooter() + { + String timeStamp = getTimeStamp(); + + try + { + logFileWriter.write(FINISH_COMMENT_MARKER + pduLogEncoding + ", " + timeStamp + ", DIS capture file, " + logFile.getPath()); + ((PrintWriter) logFileWriter).println(); + } + catch (IOException ex) + { + Logger.getLogger(PduRecorder.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private String getTimeStamp() { + // https://stackoverflow.com/questions/5175728/how-to-get-the-current-date-time-in-java + return new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime()); + } + + /** + * Rotates through file names so that no present file get overwritten. + * + * @param outputDir the directory to place the log file + * @param filename the name of the file w/ extension + * @return a File reference to the log file + * @throws IOException if something goes awry + */ + private File createUniquePduLogFile(Path outputDir, String filename) throws IOException { - System.out.println("Cannot create dis log file at " + newFile.getAbsolutePath()); - throw new RuntimeException("File creation error"); + String baseName = FilenameUtils.getBaseName(filename); + String extension = FilenameUtils.getExtension(filename); + + Integer fileCounter = null; + File newFile; + boolean fileExists; + outputDir.toFile().mkdirs(); + do { + String nextFileName = baseName + (fileCounter == null ? "" : fileCounter) + "." + extension; + newFile = new File(outputDir.toFile(), nextFileName); + fileExists = newFile.exists(); + if (fileCounter == null) + fileCounter = 1; + else + fileCounter++; + } while (fileExists); + + if (newFile.createNewFile()) + { + System.out.println("Recorder log file open: " + newFile.getCanonicalPath()); + } + else + { + System.out.println("Cannot create dis log file at " + newFile.getAbsolutePath()); + throw new RuntimeException("File creation error"); + } + return newFile; } - return newFile; - } /** * @return the pduRecorderRunning @@ -486,4 +501,99 @@ public class PduRecorder implements PduReceiver this.descriptor = newDescriptor; TRACE_PREFIX = "[" + (DisThreadedNetworkInterface.class.getSimpleName() + " " + descriptor).trim() + "] "; } + /** + * Set whether or not trace statements are provided when packets are sent or received. + * @param newValue the verbose status to set. Also resets verboseReceipt and verboseSending to match. + * @see verboseReceipt + * @see verboseSending + */ + public void setVerbose(boolean newValue) + { + this.verbose = newValue; + verboseReceipt = verbose; + verboseSending = verbose; + if (disThreadedNetworkInterface != null) + { + disThreadedNetworkInterface.setVerbose(newValue); + } + } + /** + * Whether or not trace statements are provided when packets are sent or received. + * @return the verbose status + * @see verboseReceipt + * @see verboseSending + */ + public boolean hasVerboseOutput() + { + return verbose; + } + /** + * Set whether or not trace statements are provided when packets are received. + * @param newValue the verboseReceipt status to set + * @see verbose + * @see verboseSending + */ + public void setVerboseReceipt(boolean newValue) + { + this.verboseReceipt = newValue; + verbose = (verboseReceipt || verboseSending); + if (disThreadedNetworkInterface != null) + { + disThreadedNetworkInterface.setVerboseReceipt(newValue); + } + } + /** + * Whether or not trace statements are provided when packets are received. + * @return the verboseReceipt status + */ + public boolean hasVerboseReceipt() + { + return verboseReceipt; + } + + /** + * Set whether or not trace statements are provided when packets are sent. + * @param newValue the verboseSending status to set + * @see verbose + * @see verboseReceipt + */ + public void setVerboseSending(boolean newValue) + { + this.verboseSending = newValue; + verbose = (verboseReceipt || verboseSending); + if (disThreadedNetworkInterface != null) + { + disThreadedNetworkInterface.setVerboseSending(newValue); + } + } + /** + * Whether or not trace statements are provided when packets are sent. + * @return the verboseSending status + */ + public boolean hasVerboseSending() + { + return verboseSending; + } + + /** + * Whether or not trace statements include timestamp values. + * @return the verboseIncludesTimestamp value + */ + public boolean hasVerboseOutputIncludesTimestamp() + { + return verboseIncludesTimestamp; + } + + /** + * Set whether or not trace statements include timestamp values. + * @param verboseIncludesTimestamp the value to set + */ + public void setVerboseIncludesTimestamp(boolean verboseIncludesTimestamp) + { + this.verboseIncludesTimestamp = verboseIncludesTimestamp; + if (disThreadedNetworkInterface != null) + { + disThreadedNetworkInterface.setVerboseIncludesTimestamp(verboseIncludesTimestamp); + } + } }