diff --git a/BrennenstuhlTobias/src/PduStreamTools/Compressor.java b/BrennenstuhlTobias/src/PduStreamTools/Compressor.java index 3d95fabc3a7eea196cc30b3c8af7f6bc5ae6b271..a76e263234c5e7099d327397590b27a849f53d01 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/Compressor.java +++ b/BrennenstuhlTobias/src/PduStreamTools/Compressor.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package PduStreamTools; +package DISTools; import static java.lang.Math.pow; import static java.lang.Math.sqrt; diff --git a/BrennenstuhlTobias/src/PduStreamTools/Coordinates.java b/BrennenstuhlTobias/src/PduStreamTools/Coordinates.java index d65cc02f9a1400402ab938899fd9514ea3439960..2f2c85b9f17ff3678d03de4746096e2be486f31e 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/Coordinates.java +++ b/BrennenstuhlTobias/src/PduStreamTools/Coordinates.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package PduStreamTools; +package DISTools; /** * diff --git a/BrennenstuhlTobias/src/PduStreamTools/EspduReceiver.java b/BrennenstuhlTobias/src/PduStreamTools/EspduReceiver.java deleted file mode 100644 index 9e09d082239d59a4b27b430dd4d39abe44af03c5..0000000000000000000000000000000000000000 --- a/BrennenstuhlTobias/src/PduStreamTools/EspduReceiver.java +++ /dev/null @@ -1,111 +0,0 @@ -package PduStreamTools; - -import java.io.*; -import java.net.*; -import java.util.*; - -import edu.nps.moves.dis7.*; -import edu.nps.moves.dis7.util.*; - -/** - * Receives PDUs from the network in IEEE DIS format. - * Adapted from OpenDIS library example package edu.nps.moves.examples - * - * @author DMcG - * @version $Id:$ - */ -public class EspduReceiver -{ - /** 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 multicast group address we send on. */ - public String DEFAULT_MULTICAST_ADDRESS; - - /** Default multicast port used, matches Wireshark DIS capture default */ - public int DEFAULT_MULTICAST_PORT; - - public String receive(String localBroadCastAddress, int localPort) - { - System.out.println("DisExamplesOpenDis7.EspduReceiver started..."); - - String returnString; - returnString = new String("Test Return Receiver \n"); - - this.DEFAULT_MULTICAST_ADDRESS = localBroadCastAddress; - this.DEFAULT_MULTICAST_PORT = localPort; - - - MulticastSocket socket; - DatagramPacket packet; - InetAddress address; - PduFactory pduFactory = new PduFactory(); - - try { - // Specify the socket to receive data - socket = new MulticastSocket(DEFAULT_MULTICAST_PORT); -// socket.setBroadcast(true); - - address = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); - socket.joinGroup(address); - - - 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()); - returnString += "Bundle size is "+ pduBundle.size(); - Iterator iterator = pduBundle.iterator(); - - while (iterator.hasNext()) - { - Pdu aPdu = (Pdu)iterator.next(); - String receiptMessage = "received PDU type " + aPdu.getPduType().getValue() + "=" + aPdu.getPduType().name() + " " + aPdu.getClass().getName(); - if (aPdu instanceof EntityStatePdu) - { - System.out.println("==============="); - returnString += "===============\n"; - System.out.println(receiptMessage); - returnString += receiptMessage + "\n"; - EntityID entityID = ((EntityStatePdu)aPdu).getEntityID(); - Vector3Double position = ((EntityStatePdu)aPdu).getEntityLocation(); - System.out.println(" entityID triplet: [" + entityID.getSiteID()+ ", " + entityID.getApplicationID()+ ", " + entityID.getEntityID()+ "] "); - returnString += " entityID triplet: [" + entityID.getSiteID()+ ", " + entityID.getApplicationID()+ ", " + entityID.getEntityID()+ "] "; - System.out.println(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]\n"); - returnString += " Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]\n"; - } - else if (aPdu instanceof FirePdu) - { - System.out.println(receiptMessage); - returnString += receiptMessage + "\n"; - Vector3Double position = ((FirePdu)aPdu).getLocationInWorldCoordinates(); - System.out.println(" FirePdu locationInWorldCoordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]"); - returnString += " FirePdu locationInWorldCoordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]\n"; - } - else - { - System.out.println(receiptMessage); - returnString += receiptMessage + "\n"; - } - } // end iterator loop through PDU bundle - - } // end try block - catch (IOException e) - { - System.out.println("Problem with DisExamplesOpenDis7.EspduReceiver, see exception trace:"); - returnString += "Problem with DisExamplesOpenDis7.EspduReceiver, see exception trace:\n"; - System.out.println(e); - returnString += e + "\n"; - } - System.out.println("DisExamplesOpenDis7.EspduReceiver complete."); - - return returnString; - - } // end main -} // end class diff --git a/BrennenstuhlTobias/src/PduStreamTools/EspduSender.java b/BrennenstuhlTobias/src/PduStreamTools/EspduSender.java deleted file mode 100644 index 6185c1dde19fb7c362e96759dfee42a80f088033..0000000000000000000000000000000000000000 --- a/BrennenstuhlTobias/src/PduStreamTools/EspduSender.java +++ /dev/null @@ -1,361 +0,0 @@ -package PduStreamTools; - -import java.io.*; -import java.net.*; -import java.util.*; - -import edu.nps.moves.dis7.*; -import edu.nps.moves.dis7.util.*; - -/** - * 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 -{ - public static final int NUMBER_TO_SEND = 1; // 5000 - - /** - * Default multicast group address we send on. - */ - public String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; - - /** - * Default multicast port used, matches Wireshark DIS capture default - */ - public int DEFAULT_MULTICAST_PORT = 3000; - - public enum NetworkMode { - UNICAST, MULTICAST, BROADCAST - }; - - /** - * 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 localBroadCastAddress - * @param localPort - * @return - */ - public String send(String localBroadCastAddress, int localPort) - { - String returnString; - returnString = new String(); - this.DEFAULT_MULTICAST_ADDRESS = localBroadCastAddress; - this.DEFAULT_MULTICAST_PORT = localPort; - - - System.out.println("DisExamplesOpenDis7.EspduSender 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(); - - // ICBM coordinates for my office - double latitude = 36.595517; - double longitude = -121.877000; - try - { - address = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); - } - catch (UnknownHostException e) - { - System.out.println(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); - } - } // end networkModeString - } - catch (IOException | RuntimeException e) - { - System.out.println("Unable to initialize network correctly, exiting."); - System.out.println(e); - System.exit(-1); // outta here - } - - // 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); - - // 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. - - // 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 - */ - Set<InetAddress> broadcastAddresses; - - try // Loop through sending N ESPDUs - { - System.out.println("Sending " + NUMBER_TO_SEND + " sets of packets:"); // + address.toString() - - for (int index = 0; index < NUMBER_TO_SEND; 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((double) (-1.0), (double) (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("==============="); - returnString += "===============\n"; - System.out.println("Create new PDUs"); - returnString += "Create new PDU\n"; - System.out.println(" latitude, longitude: [" + latitude + ", " + longitude + "]"); - returnString += " latitude, longitude: [" + latitude + ", " + longitude + "]\n"; - System.out.println(" coordinate conversion: [" + disCoordinates[0] + ", " + disCoordinates[1] + ", " + disCoordinates[2] + "]"); - returnString += " coordinate conversion: [" + disCoordinates[0] + ", " + disCoordinates[1] + ", " + disCoordinates[2] + "]\n"; - location = espdu.getEntityLocation(); - - System.out.println("Espdu #" + index + " entityID=[" + entityID.getSiteID()+ "," + entityID.getApplicationID()+ "," + entityID.getEntityID()+ "]"); - returnString += "Espdu #" + index + " entityID=[" + entityID.getSiteID()+ "," + entityID.getApplicationID()+ "," + entityID.getEntityID()+ "]\n"; - 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. - 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(); - - broadcastAddresses = getBroadcastAddresses(); - Iterator iterator = broadcastAddresses.iterator(); - while (iterator.hasNext()) - { - InetAddress broadcast = (InetAddress) iterator.next(); - if (espduArray.length > 0) - { - System.out.println("Sending espdu datagram packet to " + broadcast); - returnString += "Sending espdu datagram packet to " + broadcast + "\n"; - 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); - returnString += "Sending fire datagram packet to " + broadcast + "\n"; - packet = new DatagramPacket(fireArray, fireArray.length, broadcast, 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(e); - } - System.out.println("==============="); - System.out.println("DisExamplesOpenDis7.EspduSender complete."); - - return returnString; - } - - /** - * 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()) - { - Iterator iterator = anInterface.getInterfaceAddresses().iterator(); - while (iterator.hasNext()) - { - InterfaceAddress anAddress = (InterfaceAddress) iterator.next(); - 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(e); - } - return broadcastAddresses; - } -} diff --git a/BrennenstuhlTobias/src/PduStreamTools/PduListenerSaver.java b/BrennenstuhlTobias/src/PduStreamTools/PduListenerSaver.java index 23d5f786fbc596fa47b670552daba59ae61787d1..9ce3d5cafa3710084ea4b3a2c63e7c88dd2ec7ee 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/PduListenerSaver.java +++ b/BrennenstuhlTobias/src/PduStreamTools/PduListenerSaver.java @@ -8,85 +8,76 @@ import java.io.IOException; import java.util.Scanner; /** - * PduSaver.java created on Aug 21, 2019 - * MOVES Institute Naval Postgraduate School, Monterey, CA, USA www.nps.edu + * PduSaver.java created on Aug 21, 2019 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_OUTPUTDIR = "pduLog"; - private final static String MCAST_ADDR = "239.1.2.3"; - private final static int DIS_PORT = 3000; +public class PduListenerSaver { - private enum mystate - { - RUNNING, - PAUSED; - } + private final static String DEFAULT_OUTPUTDIR = "pduLog"; + private final static String MCAST_ADDR = "239.1.2.3"; + private final static int DIS_PORT = 3000; - public static void main(String[] args) - { - String outDir = DEFAULT_OUTPUTDIR; - String mcast = MCAST_ADDR; - int port = DIS_PORT; - - System.out.println("DisExamplesOpenDis7.PduListenerSaver started..."); - - switch (args.length) { - case 0: - break; - case 1: - outDir = args[0]; - break; - case 3: - outDir = args[0]; - mcast = args[1]; - port = Integer.parseInt(args[2]); - break; - default: - System.err.println("Usage: PduListener() or PduListener(\"outputdir\") or PduListener(\"outputdir\",\"multicast address\", ipPort"); - System.exit(1); + private enum mystate { + RUNNING, + PAUSED; } - System.out.println("Beginning pdu save to directory " + outDir); - try { - - //RecorderTobi stores an unencoded PduLog - RecorderTobi recorder = new RecorderTobi(outDir, mcast, port); - //Recorder stores a BASE64 encoded PduLod - //Recorder recorder = new Recorder(outDir, mcast, port); - - recorder.startResume(); - mystate state = mystate.RUNNING; - System.out.println("* recorder.startResume(), state=RUNNING, recording in progress..."); - Scanner scan = new Scanner(System.in); + public static void main(String[] args) throws IOException { + String outDir = DEFAULT_OUTPUTDIR; + String mcast = MCAST_ADDR; + int port = DIS_PORT; - while (true) { - System.out.println("Warning: you must quit when complete, otherwise recorded PDUs are lost!"); - System.out.println("Type p/enter to pause, r/enter to resume, q/enter to stop recording, save and quit"); - String line = scan.nextLine(); - if (line.equalsIgnoreCase("p") && state == mystate.RUNNING) { - recorder.stopPause(); - state = mystate.PAUSED; - System.out.println("* recorder.stopPause(), state=PAUSED, recording paused..."); - } - else if (line.equalsIgnoreCase("r") && state == mystate.PAUSED) { - recorder.startResume(); - state = mystate.RUNNING; - System.out.println("* recorder.startResume(), state=RUNNING, recording in progress..."); + System.out.println("DisExamplesOpenDis7.PduListenerSaver started..."); + + switch (args.length) { + case 0: + break; + case 1: + outDir = args[0]; + break; + case 3: + outDir = args[0]; + mcast = args[1]; + port = Integer.parseInt(args[2]); + break; + default: + System.err.println("Usage: PduListener() or PduListener(\"outputdir\") or PduListener(\"outputdir\",\"multicast address\", ipPort"); + System.exit(1); } - else if (line.equalsIgnoreCase("q")) { - recorder.end(); - System.out.println("* recorder.end(), recording complete."); - break; + + System.out.println("Beginning pdu save to directory " + outDir); + //RecorderPlainText stores an unencoded PduLog + //RecorderPlainText recorder = new RecorderPlainText(outDir, mcast, port); + //RecorderBase64 stores a BASE64 encoded PduLog + //RecorderBase64 recorder = new RecorderBase64(outDir, mcast, port); + //RecorderBinary stores a Binary PduLog + RecorderBinary recorder = new RecorderBinary(outDir, mcast, port); + + recorder.startResume(); + mystate state = mystate.RUNNING; + System.out.println("* recorder.startResume(), state=RUNNING, recording in progress..."); + Scanner scan = new Scanner(System.in); + while (true) { + System.out.println("Warning: you must quit when complete, otherwise recorded PDUs are lost!"); + System.out.println("Type p/enter to pause, r/enter to resume, q/enter to stop recording, save and quit"); + String line = scan.nextLine(); + if (line.equalsIgnoreCase("p") && state == mystate.RUNNING) { + recorder.stopPause(); + state = mystate.PAUSED; + System.out.println("* recorder.stopPause(), state=PAUSED, recording paused..."); + } else if (line.equalsIgnoreCase("r") && state == mystate.PAUSED) { + recorder.startResume(); + state = mystate.RUNNING; + System.out.println("* recorder.startResume(), state=RUNNING, recording in progress..."); + } else if (line.equalsIgnoreCase("q")) { + recorder.end(); + System.out.println("* recorder.end(), recording complete."); + break; + } } - } - System.out.println("Ending pdu save to "+recorder.getLogFile()); - } - catch (IOException ex) { - System.err.println("*** Exception: " + ex.getClass().getSimpleName() + ": " + ex.getLocalizedMessage()); + System.out.println("Ending pdu save to " + recorder.getLogFile()); } - } } diff --git a/BrennenstuhlTobias/src/PduStreamTools/PduReaderPlayer.java b/BrennenstuhlTobias/src/PduStreamTools/PduReaderPlayer.java index a1dbaef12db9cac84d52535372e2232822452e47..d4f7b941ee429bb34eaff722fd3de8610e67ae5d 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/PduReaderPlayer.java +++ b/BrennenstuhlTobias/src/PduStreamTools/PduReaderPlayer.java @@ -53,10 +53,11 @@ public class PduReaderPlayer { try { //Use Tobis Code without decryption //Does only work with unecrypted PduLogs - PlayerTobi player = new PlayerTobi(mcast, port, new File(outDir).toPath()); - - //Use Mikes Code - //Player player = new Player(mcast, port, new File(outDir).toPath()); + //PlayerPlainText player = new PlayerPlainText(mcast, port, new File(outDir).toPath()); + //Use Mike Baileys Code to store a file in BASE64 format + PlayerBase64 player = new PlayerBase64(mcast, port, new File(outDir).toPath()); + + player.startResume(); mystate state = mystate.RUNNING; Scanner scan = new Scanner(System.in); diff --git a/BrennenstuhlTobias/src/PduStreamTools/PduReceiver.java b/BrennenstuhlTobias/src/PduStreamTools/PduReceiver.java deleted file mode 100644 index 267f3f3b72600e2a979ea99bc24c32dac77958d7..0000000000000000000000000000000000000000 --- a/BrennenstuhlTobias/src/PduStreamTools/PduReceiver.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package PduStreamTools; - - -public interface PduReceiver -{ - void receivePdu(byte[] buff, int len); -} diff --git a/BrennenstuhlTobias/src/PduStreamTools/Player.java b/BrennenstuhlTobias/src/PduStreamTools/PlayerBase64.java similarity index 90% rename from BrennenstuhlTobias/src/PduStreamTools/Player.java rename to BrennenstuhlTobias/src/PduStreamTools/PlayerBase64.java index 2a679415f1fabc10d4270acda7053470474d24d3..cac44ee69d733aba694395862072fe6ef47bd13e 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/Player.java +++ b/BrennenstuhlTobias/src/PduStreamTools/PlayerBase64.java @@ -9,6 +9,9 @@ package PduStreamTools; * This work is licensed under the BSD open source license, available at https://www.movesinstitute.org/licenses/bsd.html */ +import static PduStreamTools.RecorderBase64.COMMENT_MARKER; +import static PduStreamTools.RecorderBase64.START_COMMENT_MARKER; +import static PduStreamTools.RecorderBase64.STOP_COMMENT_MARKER; import com.google.common.primitives.Longs; import java.io.*; @@ -19,16 +22,15 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.Base64; -import static PduStreamTools.Recorder.*; -public class Player +public class PlayerBase64 { private Path disLogDirectory; private String ip; private int port; private Thread thrd; - public Player(String ip, int port, Path disLogDirectory) throws IOException + public PlayerBase64(String ip, int port, Path disLogDirectory) throws IOException { this.disLogDirectory = disLogDirectory; this.ip = ip; @@ -56,7 +58,7 @@ public class Player System.out.println("Replaying DIS logs."); InetAddress addr = InetAddress.getByName(ip); - FilenameFilter filter = (dir, name) -> name.endsWith(Recorder.DISLOG_FILE_TAIL) && !name.startsWith("."); + FilenameFilter filter = (dir, name) -> name.endsWith(RecorderBase64.DISLOG_FILE_TAIL) && !name.startsWith("."); File[] fs = disLogDirectory.toFile().listFiles(filter); if (fs == null) @@ -221,7 +223,7 @@ public class Player { try { //new Player("230.0.0.0", 3000, new File("./pdulog").toPath()).startResume(); - new Player("230.0.0.0", 3000, new File("/Users/mike/NetbeansProjects/open-dis7-java/examples/pdulog").toPath()); + new PlayerBase64("230.0.0.0", 3000, new File("/Users/mike/NetbeansProjects/open-dis7-java/examples/pdulog").toPath()); } catch (Exception ex) { ex.printStackTrace(); diff --git a/BrennenstuhlTobias/src/PduStreamTools/PlayerTobi.java b/BrennenstuhlTobias/src/PduStreamTools/PlayerPlainText.java similarity index 95% rename from BrennenstuhlTobias/src/PduStreamTools/PlayerTobi.java rename to BrennenstuhlTobias/src/PduStreamTools/PlayerPlainText.java index 9f93a621f13e09c1043931d2180efb20a1d40247..ec315d319de2f4d47a205d526701345adffb0d69 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/PlayerTobi.java +++ b/BrennenstuhlTobias/src/PduStreamTools/PlayerPlainText.java @@ -10,9 +10,9 @@ package PduStreamTools; * rights reserved. This work is licensed under the BSD open source license, * available at https://www.movesinstitute.org/licenses/bsd.html */ -import static PduStreamTools.Recorder.COMMENT_MARKER; -import static PduStreamTools.Recorder.START_COMMENT_MARKER; -import static PduStreamTools.Recorder.STOP_COMMENT_MARKER; +import static PduStreamTools.RecorderBase64.COMMENT_MARKER; +import static PduStreamTools.RecorderBase64.START_COMMENT_MARKER; +import static PduStreamTools.RecorderBase64.STOP_COMMENT_MARKER; import com.google.common.primitives.Longs; import edu.nps.moves.dis7.EntityStatePdu; import edu.nps.moves.dis7.Pdu; @@ -35,14 +35,14 @@ import java.util.Set; import java.util.TreeMap; import java.util.regex.Pattern; -public class PlayerTobi { +public class PlayerPlainText { private Path disLogDirectory; private String ip; private int port; private Thread thrd; - public PlayerTobi(String ip, int port, Path disLogDirectory) throws IOException { + public PlayerPlainText(String ip, int port, Path disLogDirectory) throws IOException { this.disLogDirectory = disLogDirectory; this.ip = ip; this.port = port; @@ -68,7 +68,7 @@ public class PlayerTobi { System.out.println("Replaying DIS logs."); InetAddress addr = InetAddress.getByName(ip); - FilenameFilter filter = (dir, name) -> name.endsWith(Recorder.DISLOG_FILE_TAIL) && !name.startsWith("."); + FilenameFilter filter = (dir, name) -> name.endsWith(RecorderBase64.DISLOG_FILE_TAIL) && !name.startsWith("."); File[] fs = disLogDirectory.toFile().listFiles(filter); if (fs == null) { @@ -466,7 +466,7 @@ public class PlayerTobi { public static void main(String[] args) { try { //new Player("230.0.0.0", 3000, new File("./pdulog").toPath()).startResume(); - new PlayerTobi("239.1.2.3", 3000, new File("/Users/mike/NetbeansProjects/open-dis7-java/examples/pdulog").toPath()); + new PlayerPlainText("239.1.2.3", 3000, new File("/Users/mike/NetbeansProjects/open-dis7-java/examples/pdulog").toPath()); } catch (Exception ex) { ex.printStackTrace(); } diff --git a/BrennenstuhlTobias/src/PduStreamTools/Recorder.java b/BrennenstuhlTobias/src/PduStreamTools/RecorderBase64.java similarity index 88% rename from BrennenstuhlTobias/src/PduStreamTools/Recorder.java rename to BrennenstuhlTobias/src/PduStreamTools/RecorderBase64.java index fc559f5f3456db56d4ba23ebef291a62dc961093..4218aba855811273f1e64d4d83abe9b7002f1ad4 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/Recorder.java +++ b/BrennenstuhlTobias/src/PduStreamTools/RecorderBase64.java @@ -22,7 +22,7 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.Base64; -public class Recorder implements edu.nps.moves.dis7.util.playerrecorder.PduReceiver +public class RecorderBase64 implements edu.nps.moves.dis7.util.playerrecorder.PduReceiver { static String DEFAULT_OUTDIR = "./pdulog"; static String DEFAULT_FILEPREFIX = "Pdusave"; @@ -40,12 +40,12 @@ public class Recorder implements edu.nps.moves.dis7.util.playerrecorder.PduRecei private DisNetworking disnet; private Thread receiverThrd; - public Recorder() throws IOException + public RecorderBase64() throws IOException { this(DEFAULT_OUTDIR,DEFAULT_MCAST,DEFAULT_PORT); } - public Recorder(String outputDir, String mcastaddr, int port) throws IOException + public RecorderBase64(String outputDir, String mcastaddr, int port) throws IOException { logFile = makeFile(new File(outputDir).toPath(), DEFAULT_FILEPREFIX+DISLOG_FILE_TAIL ); bwr = new BufferedWriter(new FileWriter(logFile)); @@ -107,7 +107,7 @@ public class Recorder implements edu.nps.moves.dis7.util.playerrecorder.PduRecei Long startNanoTime = null; StringBuilder sb = new StringBuilder(); - //Base64.Encoder encdr = Base64.getEncoder(); + Base64.Encoder encdr = Base64.getEncoder(); int pduCount = 0; boolean headerWritten = false; boolean dosave = true; @@ -126,12 +126,10 @@ public class Recorder implements edu.nps.moves.dis7.util.playerrecorder.PduRecei //System.out.println("wrote time "+(packetRcvNanoTime - startNanoTime)); sb.setLength(0); - //sb.append(encdr.encodeToString(timeAr)); - sb.append(Arrays.toString(timeAr)); + sb.append(encdr.encodeToString(timeAr)); sb.append(','); byte[] buffsized = Arrays.copyOf(buff, len); - //sb.append(encdr.encodeToString(buffsized)); - sb.append(Arrays.toString(buffsized)); + sb.append(encdr.encodeToString(buffsized)); try { if (!headerWritten) { writeHeader(); @@ -205,8 +203,8 @@ public class Recorder implements edu.nps.moves.dis7.util.playerrecorder.PduRecei Path path = new File("./pdulog").toPath(); String filename = "Pdusave"; - Recorder recorder; - try{recorder = new Recorder();} catch(IOException ex) { + RecorderBase64 recorder; + try{recorder = new RecorderBase64();} catch(IOException ex) { System.err.println("Exception creating recorder: "+ex.getLocalizedMessage()); return; } @@ -224,7 +222,7 @@ public class Recorder implements edu.nps.moves.dis7.util.playerrecorder.PduRecei } } }); - sleep(2000L); + sleep(2000); recorder.end(); } diff --git a/BrennenstuhlTobias/src/PduStreamTools/RecorderBinary.java b/BrennenstuhlTobias/src/PduStreamTools/RecorderBinary.java new file mode 100644 index 0000000000000000000000000000000000000000..8f0f509485293a1bd487759c1561cfa2cd26308d --- /dev/null +++ b/BrennenstuhlTobias/src/PduStreamTools/RecorderBinary.java @@ -0,0 +1,234 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package PduStreamTools; + +import com.google.common.primitives.Longs; + +import edu.nps.moves.dis7.Pdu; +import edu.nps.moves.dis7.enumerations.DISPDUType; +import edu.nps.moves.dis7.util.DisNetworking; +import edu.nps.moves.dis7.util.DisNetworking.BuffAndLength; +import edu.nps.moves.dis7.util.PduFactory; +import org.apache.commons.io.FilenameUtils; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; + + +public class RecorderBinary implements PduReceiver +{ + static String DEFAULT_OUTDIR = "./pdulog"; + static String DEFAULT_FILEPREFIX = "Pdusave"; + static String DEFAULT_MCAST = "239.1.2.3"; + static int DEFAULT_PORT = 3000; + + static String DISLOG_FILE_TAIL = ".dislog"; + + public static String COMMENT_MARKER = "!"; + static String START_COMMENT_MARKER = COMMENT_MARKER + "Begin" + COMMENT_MARKER; + static String STOP_COMMENT_MARKER = COMMENT_MARKER + "End" + COMMENT_MARKER; + + private BufferedWriter bwr; + private File logFile; + private DisNetworking disnet; + private Thread receiverThrd; + + public RecorderBinary() throws IOException + { + this(DEFAULT_OUTDIR,DEFAULT_MCAST,DEFAULT_PORT); + } + + public RecorderBinary(String outputDir, String mcastaddr, int port) throws IOException + { + logFile = makeFile(new File(outputDir).toPath(), DEFAULT_FILEPREFIX+DISLOG_FILE_TAIL ); + bwr = new BufferedWriter(new FileWriter(logFile)); + + disnet = new DisNetworking(port, mcastaddr); + // Start a thread to receive and record pdus + + receiverThrd = new Thread(()->{ + int count = 1; + while(!Thread.interrupted()){ + try { + BuffAndLength blen = disnet.receiveRawPdu(); + //System.out.println(""+ count++ +" Got pdu from DisNetworking"); + receivePdu(blen.buff,blen.length); + } + catch(IOException ex) { + // this is the normal exception if you do disnet.stop() System.err.println("Exception receiving Pdu: "+ex.getLocalizedMessage()); + } + } + }); + receiverThrd.setPriority(Thread.NORM_PRIORITY); + receiverThrd.setDaemon(true); + receiverThrd.start(); + } + + public void startResume() + { + dosave = true; + } + + public void stopPause() + { + dosave = false; + } + + public String getOutputFile() + { + if(logFile != null) + return logFile.getAbsolutePath(); + return null; + } + + public void end() + { + disnet.stop(); + receiverThrd.interrupt(); + + try { + writeFooter(); + bwr.flush(); + bwr.close(); + System.out.println(); + System.out.println("Recorder log file closed"); + } + catch (IOException ex) { + System.out.println("IOException closing file: " + ex.getMessage()); + } + } + + Long startNanoTime = null; + StringBuilder sb = new StringBuilder(); + int pduCount = 0; + boolean headerWritten = false; + boolean dosave = true; + + @Override + public void receivePdu(byte[] buff, int len) + { + if(!dosave) + return; + + long packetRcvNanoTime = System.nanoTime(); + if (startNanoTime == null) + startNanoTime = packetRcvNanoTime; + + byte[] timeAr = Longs.toByteArray(packetRcvNanoTime - startNanoTime); + //System.out.println("wrote time "+(packetRcvNanoTime - startNanoTime)); + + sb.setLength(0); + sb.append(Arrays.toString(timeAr)); + sb.append(','); + byte[] buffsized = Arrays.copyOf(buff, len); + sb.append(Arrays.toString(buffsized)); + try { + if (!headerWritten) { + writeHeader(); + headerWritten = true; + } + //Added a REGEX to strip all spaces from the string before writing to file + bwr.write(sb.toString().replaceAll("\\s","")); + bwr.newLine(); + } + catch (IOException ex) { + System.err.println("Fatal exception writing DIS log file in Recorder.start()"); + throw new RuntimeException(ex); + } + System.out.print(++pduCount + "\r"); + + //bwr.flush(); + sb.setLength(0); + } + + public String getLogFile() + { + return logFile.getAbsolutePath(); + } + + private void writeHeader() throws IOException + { + String template = "Beginning of DIS capture file, %s. [PDU Header],[PDU Stream]"; + String startComment = String.format(template, logFile.getName()); + bwr.write(START_COMMENT_MARKER + startComment); + bwr.newLine(); + } + + private void writeFooter() throws IOException + { + String template = "End of DIS capture file, %s."; + String endComment = String.format(template, logFile.getName()); + bwr.write(STOP_COMMENT_MARKER + endComment); + bwr.newLine(); + } + + private File makeFile(Path outputDir, String filename) throws IOException + { + String bname = FilenameUtils.getBaseName(filename); + String ext = FilenameUtils.getExtension(filename); + + Integer count = null; + File f; + boolean fileExists; + outputDir.toFile().mkdirs(); + do { + String fn = bname + (count == null ? "" : count) + "." + ext; + f = new File(outputDir.toFile(), fn); + fileExists = f.exists(); + if (count == null) + count = 1; + else + count++; + } while (fileExists); + if (!f.createNewFile()) { + System.out.println("Cannot create dis log file at " + f.getAbsolutePath()); + throw new RuntimeException("File creation error"); + } + return f; + } + + /* Example test usage */ + public static void main(String[] args) + { + PduFactory factory = new PduFactory(); //default appid, country, etc. + DisNetworking disnet = new DisNetworking(); // default ip and port + + Path path = new File("./pdulog").toPath(); + String filename = "Pdusave"; + + RecorderBinary recorder; + try{recorder = new RecorderBinary();} catch(IOException ex) { + System.err.println("Exception creating recorder: "+ex.getLocalizedMessage()); + return; + } + + DISPDUType all[] = DISPDUType.values(); + Arrays.stream(all).forEach(typ-> { + if(typ != DISPDUType.OTHER) { + try { + Pdu pdu = factory.createPdu(typ); + disnet.sendPdu(pdu); + sleep(100); + } + catch(Exception ex) { + System.err.println("Exception sending Pdu: "+ex.getLocalizedMessage()); + } + } + }); + sleep(2000); + + recorder.end(); + } + + private static void sleep(long ms) + { + try{Thread.sleep(ms);}catch(InterruptedException ex) {} + } +} diff --git a/BrennenstuhlTobias/src/PduStreamTools/RecorderTobi.java b/BrennenstuhlTobias/src/PduStreamTools/RecorderPlainText.java similarity index 92% rename from BrennenstuhlTobias/src/PduStreamTools/RecorderTobi.java rename to BrennenstuhlTobias/src/PduStreamTools/RecorderPlainText.java index 9214d5a20ce3ff884157257350b3c96cae442a33..3013cd7ff2479d0c77f8e826e04057f4c6cd94a4 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/RecorderTobi.java +++ b/BrennenstuhlTobias/src/PduStreamTools/RecorderPlainText.java @@ -22,7 +22,7 @@ import java.nio.file.Path; import java.util.Arrays; -public class RecorderTobi implements PduReceiver +public class RecorderPlainText implements PduReceiver { static String DEFAULT_OUTDIR = "./pdulog"; static String DEFAULT_FILEPREFIX = "Pdusave"; @@ -40,12 +40,12 @@ public class RecorderTobi implements PduReceiver private DisNetworking disnet; private Thread receiverThrd; - public RecorderTobi() throws IOException + public RecorderPlainText() throws IOException { this(DEFAULT_OUTDIR,DEFAULT_MCAST,DEFAULT_PORT); } - public RecorderTobi(String outputDir, String mcastaddr, int port) throws IOException + public RecorderPlainText(String outputDir, String mcastaddr, int port) throws IOException { logFile = makeFile(new File(outputDir).toPath(), DEFAULT_FILEPREFIX+DISLOG_FILE_TAIL ); bwr = new BufferedWriter(new FileWriter(logFile)); @@ -206,8 +206,8 @@ public class RecorderTobi implements PduReceiver Path path = new File("./pdulog").toPath(); String filename = "Pdusave"; - RecorderTobi recorder; - try{recorder = new RecorderTobi();} catch(IOException ex) { + RecorderPlainText recorder; + try{recorder = new RecorderPlainText();} catch(IOException ex) { System.err.println("Exception creating recorder: "+ex.getLocalizedMessage()); return; } diff --git a/BrennenstuhlTobias/src/PduStreamTools/SimpleSenderGUI.java b/BrennenstuhlTobias/src/PduStreamTools/SimpleSenderGUI.java index 42ff76c9700016f13e2f16bbee389dc111edcb85..f7ba040921c02ac11bfedbb629b94012e6845bfb 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/SimpleSenderGUI.java +++ b/BrennenstuhlTobias/src/PduStreamTools/SimpleSenderGUI.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package PduStreamTools; +package DISTools; import java.awt.BorderLayout; import java.awt.GridLayout; diff --git a/BrennenstuhlTobias/src/PduStreamTools/SimpleSenderGUIMain.java b/BrennenstuhlTobias/src/PduStreamTools/SimpleSenderGUIMain.java index d381a7af1fe146e27474ed7cbe620bf73300623b..2fd483f117954fa8781fe3af64069286efd8efdc 100644 --- a/BrennenstuhlTobias/src/PduStreamTools/SimpleSenderGUIMain.java +++ b/BrennenstuhlTobias/src/PduStreamTools/SimpleSenderGUIMain.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package PduStreamTools; +package DISTools; import javax.swing.SwingUtilities;