Skip to content
Snippets Groups Projects
Commit 9acdb49d authored by Brutzman, Don's avatar Brutzman, Don
Browse files

socket.joinGroup updated to include networkInterface

parent d6e2fc7b
No related branches found
No related tags found
No related merge requests found
examples/src/OpenDis4Examples/EspduSenderWireshark.png

120 KiB

......@@ -31,7 +31,13 @@ public class PduReceiver
System.out.println("OpenDis4Examples.PduReceiver started...");
socket = new MulticastSocket (MULTICAST_PORT);
address = InetAddress.getByName(MULTICAST_GROUP);
socket.joinGroup(address);
// socket.joinGroup(address); // deprecated
// =======================================================================
// new approach using interface
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(address);
SocketAddress localMulticastSocketAddress = new InetSocketAddress(address, MULTICAST_PORT);
socket.joinGroup(localMulticastSocketAddress, networkInterface);
// =======================================================================
factory = new PduFactory();
......
run:
DisExamples.PduReceiver started...
ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis4Examples/PduReceiver.java -Drun.class=OpenDis4Examples.PduReceiver run-single
init:
Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties
deps-jar:
Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties
Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes
compile-single:
run-single:
OpenDis4Examples.PduReceiver started...
received DIS PDU: pduType 1 edu.nps.moves.dis.EntityStatePdu, protocolFamily 1 EntityInformationFamilyPdu
received DIS PDU: pduType 2 edu.nps.moves.dis.FirePdu, protocolFamily 2 WarfareFamilyPdu
received DIS PDU: pduType 3 edu.nps.moves.dis.DetonationPdu, protocolFamily 2 WarfareFamilyPdu
......
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);
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().getName());
}
// 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();
}
}
}
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().getName());
}
// 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();
}
}
}
Invocation instructions:
1. run/debug PduSender.java
Program response:
===================================================
run:
Usage: PduSender <port> <multicast group>
Default: PduSender 3000 239.1.2.3
DisExamples.PduSender started...
PDU of type OTHER not supported, created or sent
PDU of type ACTION_RESPONSE not supported, created or sent
PDU of type DATA_QUERY not supported, created or sent
PDU of type SET_DATA not supported, created or sent
PDU of type DATA not supported, created or sent
PDU of type EVENT_REPORT not supported, created or sent
PDU of type ELECTROMAGNETIC_EMISSION not supported, created or sent
PDU of type DESIGNATOR not supported, created or sent
PDU of type TRANSMITTER not supported, created or sent
PDU of type SIGNAL not supported, created or sent
PDU of type RECEIVER not supported, created or sent
PDU of type IFF_ATC_NAVAIDS not supported, created or sent
PDU of type UNDERWATER_ACOUSTIC not supported, created or sent
PDU of type SUPPLEMENTAL_EMISSION_ENTITY_STATE not supported, created or sent
PDU of type INTERCOM_SIGNAL not supported, created or sent
PDU of type INTERCOM_CONTROL not supported, created or sent
PDU of type AGGREGATE_STATE not supported, created or sent
PDU of type ISGROUPOF not supported, created or sent
PDU of type TRANSFER_CONTROL not supported, created or sent
PDU of type ISPARTOF not supported, created or sent
PDU of type MINEFIELD_STATE not supported, created or sent
PDU of type MINEFIELD_QUERY not supported, created or sent
PDU of type MINEFIELD_DATA not supported, created or sent
PDU of type MINEFIELD_RESPONSE_NAK not supported, created or sent
PDU of type ENVIRONMENTAL_PROCESS not supported, created or sent
PDU of type GRIDDED_DATA not supported, created or sent
PDU of type POINT_OBJECT_STATE not supported, created or sent
PDU of type LINEAR_OBJECT_STATE not supported, created or sent
PDU of type AREAL_OBJECT_STATE not supported, created or sent
PDU of type TSPI not supported, created or sent
PDU of type APPEARANCE not supported, created or sent
PDU of type ARTICULATED_PARTS not supported, created or sent
PDU of type LE_FIRE not supported, created or sent
PDU of type LE_DETONATION not supported, created or sent
PDU of type CREATE_ENTITY_R not supported, created or sent
PDU of type REMOVE_ENTITY_R not supported, created or sent
PDU of type START_RESUME_R not supported, created or sent
PDU of type STOP_FREEZE_R not supported, created or sent
PDU of type ACKNOWLEDGE_R not supported, created or sent
PDU of type ACTION_REQUEST_R not supported, created or sent
PDU of type ACTION_RESPONSE_R not supported, created or sent
PDU of type DATA_QUERY_R not supported, created or sent
PDU of type SET_DATA_R not supported, created or sent
PDU of type DATA_R not supported, created or sent
PDU of type EVENT_REPORT_R not supported, created or sent
PDU of type COMMENT_R not supported, created or sent
PDU of type RECORD_R not supported, created or sent
PDU of type SET_RECORD_R not supported, created or sent
PDU of type RECORD_QUERY_R not supported, created or sent
PDU of type COLLISION_ELASTIC not supported, created or sent
PDU of type ENTITY_STATE_UPDATE not supported, created or sent
Send the 17 PDUs we created...
Sent PDU of type edu.nps.moves.dis.EntityStatePdu
Sent PDU of type edu.nps.moves.dis.FirePdu
Sent PDU of type edu.nps.moves.dis.DetonationPdu
Sent PDU of type edu.nps.moves.dis.CollisionPdu
Sent PDU of type edu.nps.moves.dis.ServiceRequestPdu
Sent PDU of type edu.nps.moves.dis.ResupplyOfferPdu
Sent PDU of type edu.nps.moves.dis.ResupplyReceivedPdu
Sent PDU of type edu.nps.moves.dis.ResupplyCancelPdu
Sent PDU of type edu.nps.moves.dis.RepairCompletePdu
Sent PDU of type edu.nps.moves.dis.RepairResponsePdu
Sent PDU of type edu.nps.moves.dis.CreateEntityPdu
Sent PDU of type edu.nps.moves.dis.RemoveEntityPdu
Sent PDU of type edu.nps.moves.dis.StartResumePdu
Sent PDU of type edu.nps.moves.dis.StopFreezePdu
Sent PDU of type edu.nps.moves.dis.AcknowledgePdu
Sent PDU of type edu.nps.moves.dis.ActionRequestPdu
Sent PDU of type edu.nps.moves.dis.CommentPdu
BUILD SUCCESSFUL (total time: 1 second)
ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\examples -Dnb.internal.action.name=run.single -Djavac.includes=OpenDis4Examples/PduSender.java -Drun.class=OpenDis4Examples.PduSender run-single
init:
Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties
deps-jar:
Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties
Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes
compile-single:
run-single:
Usage: PduSender <port> <multicast group>
Default: PduSender 3000 239.1.2.3
OpenDis4Examples.PduSender started...
PDU of type OTHER not supported, created or sent
PDU of type ACTION_RESPONSE not supported, created or sent
PDU of type DATA_QUERY not supported, created or sent
PDU of type SET_DATA not supported, created or sent
PDU of type DATA not supported, created or sent
PDU of type EVENT_REPORT not supported, created or sent
PDU of type ELECTROMAGNETIC_EMISSION not supported, created or sent
PDU of type DESIGNATOR not supported, created or sent
PDU of type TRANSMITTER not supported, created or sent
PDU of type SIGNAL not supported, created or sent
PDU of type RECEIVER not supported, created or sent
PDU of type IFF_ATC_NAVAIDS not supported, created or sent
PDU of type UNDERWATER_ACOUSTIC not supported, created or sent
PDU of type SUPPLEMENTAL_EMISSION_ENTITY_STATE not supported, created or sent
PDU of type INTERCOM_SIGNAL not supported, created or sent
PDU of type INTERCOM_CONTROL not supported, created or sent
PDU of type AGGREGATE_STATE not supported, created or sent
PDU of type ISGROUPOF not supported, created or sent
PDU of type TRANSFER_CONTROL not supported, created or sent
PDU of type ISPARTOF not supported, created or sent
PDU of type MINEFIELD_STATE not supported, created or sent
PDU of type MINEFIELD_QUERY not supported, created or sent
PDU of type MINEFIELD_DATA not supported, created or sent
PDU of type MINEFIELD_RESPONSE_NAK not supported, created or sent
PDU of type ENVIRONMENTAL_PROCESS not supported, created or sent
PDU of type GRIDDED_DATA not supported, created or sent
PDU of type POINT_OBJECT_STATE not supported, created or sent
PDU of type LINEAR_OBJECT_STATE not supported, created or sent
PDU of type AREAL_OBJECT_STATE not supported, created or sent
PDU of type TSPI not supported, created or sent
PDU of type APPEARANCE not supported, created or sent
PDU of type ARTICULATED_PARTS not supported, created or sent
PDU of type LE_FIRE not supported, created or sent
PDU of type LE_DETONATION not supported, created or sent
PDU of type CREATE_ENTITY_R not supported, created or sent
PDU of type REMOVE_ENTITY_R not supported, created or sent
PDU of type START_RESUME_R not supported, created or sent
PDU of type STOP_FREEZE_R not supported, created or sent
PDU of type ACKNOWLEDGE_R not supported, created or sent
PDU of type ACTION_REQUEST_R not supported, created or sent
PDU of type ACTION_RESPONSE_R not supported, created or sent
PDU of type DATA_QUERY_R not supported, created or sent
PDU of type SET_DATA_R not supported, created or sent
PDU of type DATA_R not supported, created or sent
PDU of type EVENT_REPORT_R not supported, created or sent
PDU of type COMMENT_R not supported, created or sent
PDU of type RECORD_R not supported, created or sent
PDU of type SET_RECORD_R not supported, created or sent
PDU of type RECORD_QUERY_R not supported, created or sent
PDU of type COLLISION_ELASTIC not supported, created or sent
PDU of type ENTITY_STATE_UPDATE not supported, created or sent
Send the 17 PDUs we created...
Sent PDU of type edu.nps.moves.dis.EntityStatePdu
Sent PDU of type edu.nps.moves.dis.FirePdu
Sent PDU of type edu.nps.moves.dis.DetonationPdu
Sent PDU of type edu.nps.moves.dis.CollisionPdu
Sent PDU of type edu.nps.moves.dis.ServiceRequestPdu
Sent PDU of type edu.nps.moves.dis.ResupplyOfferPdu
Sent PDU of type edu.nps.moves.dis.ResupplyReceivedPdu
Sent PDU of type edu.nps.moves.dis.ResupplyCancelPdu
Sent PDU of type edu.nps.moves.dis.RepairCompletePdu
Sent PDU of type edu.nps.moves.dis.RepairResponsePdu
Sent PDU of type edu.nps.moves.dis.CreateEntityPdu
Sent PDU of type edu.nps.moves.dis.RemoveEntityPdu
Sent PDU of type edu.nps.moves.dis.StartResumePdu
Sent PDU of type edu.nps.moves.dis.StopFreezePdu
Sent PDU of type edu.nps.moves.dis.AcknowledgePdu
Sent PDU of type edu.nps.moves.dis.ActionRequestPdu
Sent PDU of type edu.nps.moves.dis.CommentPdu
BUILD SUCCESSFUL (total time: 2 seconds)
examples/src/OpenDis4Examples/PduSenderWireshark.png

116 KiB

# DIS Protocol Examples using Open-DIS-4 Java Library
*Note:* these examples demonstrate an earlier version of Open-DIS-Java Library. Please work with current version [OpenDis7Examples](../OpenDis7Examples) instead.
*Note:* these archived examples demonstrate an earlier version of Open-DIS-Java Library.
Please work with current version [OpenDis7Examples](../OpenDis7Examples) instead.
---
......
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