Skip to content
Snippets Groups Projects
PduSender.java 8.08 KiB
package OpenDis4Examples;

import java.io.*;
import java.net.*;
import java.util.*;

import edu.nps.moves.dis.*;
import edu.nps.moves.disenum.*;
import edu.nps.moves.examples.ClassNameComparator;

/**
 * This is an example that sends many/most types of PDUs. Useful for testing standards
 * compliance or getting a full set of PDUs. It also writes the generated PDUs to an XML file.
 * Adapted from OpenDIS library example package edu.nps.moves.examples
 *
 * @author DMcG
 * @version $Id:$
 */
public class PduSender
{
    /** Default multicast group address we send on.
      * @see <a href="https://en.wikipedia.org/wiki/Multicast_address">https://en.wikipedia.org/wiki/Multicast_address</a> */
    private static final String DEFAULT_MULTICAST_ADDRESS = "239.1.2.3";
	
    /** Default multicast port used, matches Wireshark DIS capture default
      * @see <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)">https://en.wikipedia.org/wiki/Port_(computer_networking)</a> */
    private static final int    DEFAULT_MULTICAST_PORT    = 3000;
	
    private int port;
    InetAddress multicastAddress;

    /** Object constructor
     * @param port port of interest
     * @param multicast address of interest */
    public PduSender(int port, String multicast) {
        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);
        }
    }

    /** Begin operations */
    public void run()
	{
		System.out.println("OpenDis4Examples.PduSender started...");
        try {
            List<Pdu> generatedPdusList = new ArrayList<>();

            // Loop through all the enumerated PDU types, create a PDU for each type,
            // add that PDU to generatedPdusList, and send each one
            for (PduType pdu : PduType.values()) 
			{
                Pdu aPdu = null; // edu.​nps.​moves.​dis,PDU superclass for all PDUs, 

                switch (pdu) // using enumeration values from edu.nps.moves.disenum.*
				{
                    case ENTITY_STATE:
                        aPdu = new EntityStatePdu();
						EntityStatePdu espdu = (EntityStatePdu) aPdu;
						Marking marking = new Marking ();
						marking.setCharactersString("PduSender"); // 11 characters max
						espdu.setMarking(marking);
						Vector3Double espduLocation = new Vector3Double();
						espduLocation.setX(1.0);
						espduLocation.setY(2.0);
						espduLocation.setZ(3.0);
						espdu.setEntityLocation(espduLocation);
						// it is important to identify questions as you think of them
						// TODO how to set azimuth, i.e. course direction over ground?
                        break;
                        
                    case COMMENT:
                        aPdu = new CommentPdu();
						CommentPdu    newCommentPdu = (CommentPdu)aPdu;
						VariableDatum newVariableDatum = new VariableDatum();
						// etc. see Garrett and Pete's code
                        break;

                    case FIRE:
                        aPdu = new FirePdu();
                        break;

                    case DETONATION:
                        aPdu = new DetonationPdu();
                        break;

                    case COLLISION:
                        aPdu = new CollisionPdu();
                        break;

                    case SERVICE_REQUEST:
                        aPdu = new ServiceRequestPdu();
                        break;

                    case RESUPPLY_OFFER:
                        aPdu = new ResupplyOfferPdu();
                        break;

                    case RESUPPLY_RECEIVED:
                        aPdu = new ResupplyReceivedPdu();
                        break;

                    case RESUPPLY_CANCEL:
                        aPdu = new ResupplyCancelPdu();
                        break;

                    case REPAIR_COMPLETE:
                        aPdu = new RepairCompletePdu();
                        break;

                    case REPAIR_RESPONSE:
                        aPdu = new RepairResponsePdu();
                        break;

                    case CREATE_ENTITY:
                        aPdu = new CreateEntityPdu();
                        break;

                    case REMOVE_ENTITY:
                        aPdu = new RemoveEntityPdu();
                        break;

                    case START_RESUME:
                        aPdu = new StartResumePdu();
                        break;

                    case STOP_FREEZE:
                        aPdu = new StopFreezePdu();
                        break;

                    case ACKNOWLEDGE:
                        aPdu = new AcknowledgePdu();
                        break;

                    case ACTION_REQUEST:
                        aPdu = new ActionRequestPdu();
                        break;

                    default:
                        System.out.print("PDU of type " + pdu + " not supported, created or sent ");
                        System.out.println();
                }
                if (aPdu != null)
				{
                    generatedPdusList.add(aPdu);
                }
            }

            // Sort the created PDUs by class name, if desired
//            Collections.sort(generatedPdusList, new ClassNameComparator());

            System.out.println("Send the " + generatedPdusList.size() + " PDUs we created...");

            // Send the PDUs we created
            InetAddress localMulticastAddress = InetAddress.getByName(DEFAULT_MULTICAST_ADDRESS);
            MulticastSocket socket = new MulticastSocket(DEFAULT_MULTICAST_PORT);
//          socket.joinGroup(localMulticastAddress); // deprecated, TODO select correct NetworkInterface
            // =======================================================================
            // updated approach using NetworkInterface
            NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localMulticastAddress);
            if (networkInterface != null)
                System.out.println("networkInterface=" + networkInterface.getDisplayName()); // typically null if loopback
            SocketAddress localMulticastSocketAddress = new InetSocketAddress(localMulticastAddress, DEFAULT_MULTICAST_PORT);
            socket.joinGroup(localMulticastSocketAddress, networkInterface);
            // =======================================================================

            for (int idx = 0; idx < generatedPdusList.size(); idx++)
			{
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                DataOutputStream dos = new DataOutputStream(baos);
                byte[] buffer;

                Pdu aPdu = generatedPdusList.get(idx);
                aPdu.marshal(dos);

                buffer = baos.toByteArray();
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length, localMulticastAddress, DEFAULT_MULTICAST_PORT);
                socket.send(packet);
                System.out.println("Sent PDU of type " + aPdu.getClass().getSimpleName());
            }
            // write the PDUs out to an XML file.
            //PduContainer container = new PduContainer();
            //container.setPdus(generatedPdus);
            //container.marshallToXml("examplePdus.xml");
        } catch (IOException e)
		{
            System.out.println(e);
        }
    }

    /**
     * Program invocation, execution starts here
     * @param args command-line arguments
     */
    public static void main(String args[])
	{
        if (args.length == 2) {
            PduSender sender = new PduSender(Integer.parseInt(args[0]), args[1]);
            sender.run();
        } else {
            System.out.println("Usage:   PduSender <port> <multicast group>");
            System.out.println("Default: PduSender  " + DEFAULT_MULTICAST_PORT + "   " + DEFAULT_MULTICAST_ADDRESS);
            PduSender sender = new  PduSender(DEFAULT_MULTICAST_PORT, DEFAULT_MULTICAST_ADDRESS);
            sender.run();
        }
    }
}