package MV3500Cohort2018JulySeptember.projects.FriscoFurr; import java.net.*; import java.io.*; import java.util.*; import edu.nps.moves.dis.*; // OpenDIS version 4 import java.io.IOException; import edu.nps.moves.disutil.PduFactory; import edu.nps.moves.disutil.DisTime; public class FDCSendRecieve { /** * Default multicast group address we send on. */ public static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3"; /** * Default multicast port used, matches Wireshark DIS capture default */ public static final int DEFAULT_MULTICAST_PORT = 3000; private int port; InetAddress multicastAddress; /** socket value of shared interest */ public static final int MULTICAST_PORT = 3000; /** socket value of shared interest */ public static final String MULTICAST_GROUP = "239.1.2.3"; private static final boolean USE_FAST_ESPDU = false; private long[] sentBuffer = new long[100]; private static List sentBufferList; DisTime disTime = DisTime.getInstance(); public FDCSendRecieve(int port, String multicast) { this.sentBufferList = new ArrayList<>(); try { this.port = port; multicastAddress = InetAddress.getByName(multicast); if (!multicastAddress.isMulticastAddress()) { System.out.println("Not a multicast address: " + multicast); } } catch (UnknownHostException e) { System.out.println("Unable to open socket: " + e); } } /** * This would be the sending Run method. Takes in several PDUs and for each one has a switch statement ready for it. * @param pdupass * @throws UnknownHostException unable to reach host address * @throws IOException input-output error */ public void run(Pdu... pdupass) throws UnknownHostException, IOException { List<Pdu> generatedPdus = new ArrayList<>(); Pdu aPdu = null; System.out.println("\nFDC Sender started..."); // Send the PDUs we created InetAddress localMulticastAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS); MulticastSocket socket = new MulticastSocket(DEFAULT_MULTICAST_PORT); socket.joinGroup(localMulticastAddress); for (Pdu i : pdupass) { Pdu pdu = i; if (sentBufferList.contains(pdu.getTimestamp())) { break; } short currentPduType = pdu.getPduType(); System.out.println("in sender, recived PDU type: " + currentPduType); switch (currentPduType) // using enumeration values from edu.nps.moves.disenum.* { case 1: //ENTITY_STATE: aPdu = pdu; break; case 2: //FIRE aPdu = pdu; break; // case 15: //AcknowledgePdu aPdu = pdu; break; case 17: aPdu = pdu; break; case 14: aPdu = pdu; break; default: System.out.print("PDU of type " + pdu + " not supported, created or sent "); System.out.println(); } if (aPdu != null) { generatedPdus.add(aPdu); System.out.println("APDU container count " + generatedPdus.size()); } } for (int idx = 0; idx < generatedPdus.size(); idx++) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); byte[] buffer; aPdu = generatedPdus.get(idx); aPdu.marshal(dos); buffer = baos.toByteArray(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, localMulticastAddress, DEFAULT_MULTICAST_PORT); socket.send(packet); sentBufferList.add(aPdu.getTimestamp()); System.out.println("Sent PDU of type " + aPdu.getClass().getName()+ "\n"); } } /** * Main function takes no specific arguments, but is the recieving portion of the code. Once it hears a specific type of PDU it creates another and sends it to the Run function * called sender created on line 130 (2nd statement in the main function) * @param args command-line arguments * @throws IOException input-output error * @throws InterruptedException interruption */ public static void main(String[] args) throws IOException, InterruptedException { DisTime disTime = DisTime.getInstance(); FDCSendRecieve sender = new FDCSendRecieve(DEFAULT_MULTICAST_PORT, DEFAULT_MULTICAST_ADDRESS); //initalize the sender EntityStatePdu FDCespdu = new EntityStatePdu(); Marking marking = new Marking(); marking.setCharactersString("FDC"); FDCespdu.setMarking(marking); FDCespdu.setExerciseID((short) 1); EntityID FDCID = FDCespdu.getEntityID(); FDCID.setSite(1); FDCID.setApplication(1); FDCID.setEntity(1); EntityType entityType = FDCespdu.getEntityType(); // //Need to update the info below to match the unit type IAW SISO-REF-010-2015 V.21 // https://www.sisostds.org/DesktopModules/Bring2mind/DMX/Download.aspx?Command=Core_Download&EntryId=42916&PortalId=0&TabId=105 // entityType.setEntityKind((short) 1); // Platform (vs lifeform, munition, sensor, etc.) TGT=1, OBS = 1 entityType.setCountry(225); // USA TGT = 222 (Russia), OBS = 225 entityType.setDomain((short) 1); // Land (vs air, surface, subsurface, space) both TGT and OBS are 1 entityType.setCategory((short) 3); // FDC TGT = 1, Tank OBS=40 OP entityType.setSubcategory((short) 12); // M1068 TGT = 2, T72 tank NONE FOR OP entityType.setSpec((short) 1); // M1068 w/ SICUP Tent NONE FOR TGT OR OP Vector3Double location = new Vector3Double(); location.setX(0.0); //TGT = 150 OBS = 75 location.setY(0.0); //TGT = 150 OBS = 75 location.setZ(10.0); //TGT = 20 OBS = 50 FDCespdu.setEntityLocation(location); int timestamp = disTime.getDisAbsoluteTimestamp(); FDCespdu.setTimestamp(timestamp); sender.run(FDCespdu); //sends inital here I am and who I am //Set up other players to look for: EntityID OBSEntityID = new EntityID(); OBSEntityID.setEntity(2); OBSEntityID.setApplication(1); OBSEntityID.setSite(1); EntityID TGTEntityID = new EntityID(); TGTEntityID.setEntity(3); TGTEntityID.setApplication(1); TGTEntityID.setSite(1); /* BELOW IS THE RECIEVE CODE // // // // // */ // PduFactory factory; MulticastSocket socket = null; InetAddress address = null; DatagramPacket packet; short currentPduType = 0; //will use the curentPduType as the check for sending other packets. try { System.out.println("FDC is alive and ready to recieve fire missions...\n\n"); socket = new MulticastSocket(MULTICAST_PORT); address = InetAddress.getByName(MULTICAST_GROUP); socket.joinGroup(address); factory = new PduFactory(); while (true) // Loop infinitely, receiving datagrams { byte buffer[] = new byte[1500]; // typical MTU size packet = new DatagramPacket(buffer, buffer.length); // reset socket.receive(packet); String marking2 = new String(); Pdu pdu = factory.createPdu(packet.getData()); currentPduType = pdu.getPduType(); if (currentPduType == 14) //stop/freeze PDU { System.out.println("recieved Stop/Freeze packet..."); return; } // pdu.setExerciseID((short)5); if (pdu != null) { if (sentBufferList.contains(pdu.getTimestamp())) { pdu = null; } if (pdu != null) { String currentPduTypeName = pdu.getClass().getName(); if (currentPduType == 1) { EntityStatePdu pdu2 = (EntityStatePdu) pdu; marking2 = pdu2.getMarking().getCharactersString(); } StringBuilder message = new StringBuilder(); message.append("received DIS PDU: "); message.append("pduType "); if (currentPduType < 10) { message.append(" "); } message.append(currentPduType).append(" ").append(currentPduTypeName); message.append(" "); message.append(marking2); System.out.println(message.toString()); //Reference for PDU Types: // http://faculty.nps.edu/brutzman/vrtp/mil/navy/nps/disEnumerations/JdbeHtmlFiles/pdu/8.htm // if (currentPduType == 1) //EntityState { EntityStatePdu entityPDU = (EntityStatePdu) pdu; EntityType PduEntityType = entityPDU.getEntityType(); if (PduEntityType.getCountry() == 225) { Thread.sleep((long) 200); timestamp = disTime.getDisAbsoluteTimestamp(); FDCespdu.setTimestamp(timestamp); System.out.println("Talking to the Observer, sending a radio check "); sender.run(FDCespdu); } } if (currentPduType == 16) //Action request { // Action response is sending a Null PDU, not sure why... so we will use the acknowledge pdu instead AcknowledgePdu ack = new AcknowledgePdu(); ack.setExerciseID((short) 1); ack.setRequestID((long) 1); timestamp = disTime.getDisAbsoluteTimestamp(); ack.setTimestamp(timestamp); //Creating a fire PDU FirePdu fire = new FirePdu(); fire.setExerciseID((short) 1); fire.setFireMissionIndex(1000); fire.setRangeToTarget((float) Math.sqrt(Math.pow(150, 2) + Math.pow(150, 2))); //would pass in target info, but here we know location of tgt is (150,150) and FDC (0,0) fire.setFiringEntityID(FDCID); fire.setTargetEntityID(TGTEntityID); timestamp = disTime.getDisAbsoluteTimestamp(); fire.setTimestamp(timestamp); sender.run(ack, fire); } if (currentPduType == 22) //Comment PDU { AcknowledgePdu ack = new AcknowledgePdu(); ack.setExerciseID((short) 1); ack.setRequestID((long) 1); timestamp = disTime.getDisAbsoluteTimestamp(); ack.setTimestamp(timestamp); //and the freeze PDU being created to stop everything. StopFreezePdu stop = new StopFreezePdu(); stop.setExerciseID((short) 1); stop.setRequestID((long) 1); sender.run(ack, stop); } } else { System.out.println("received packet but pdu is null and originated from FDC. Still standing by..."); } } } } catch (IOException e) { System.out.println("Problem with FDCSendRecieve, see exception trace:"); System.out.println(e); } finally { System.out.println("FDC SendReceive complete. - OUT!"); } } }