diff --git a/src/main/java/edu/nps/moves/dis7/AggregateMarking.java b/src/main/java/edu/nps/moves/dis7/AggregateMarking.java index 0af540b..b8fa4e8 100644 --- a/src/main/java/edu/nps/moves/dis7/AggregateMarking.java +++ b/src/main/java/edu/nps/moves/dis7/AggregateMarking.java @@ -22,7 +22,9 @@ public class AggregateMarking extends Object implements Serializable { /** * The characters */ - protected short characters; + protected byte[] characters = new byte[31]; + + ; /** * Constructor @@ -34,7 +36,7 @@ public int getMarshalledSize() { int marshalSize = 0; marshalSize = marshalSize + 1; // characterSet - marshalSize = marshalSize + 1; // characters + marshalSize = marshalSize + characters.length; // characters return marshalSize; } @@ -47,18 +49,35 @@ public short getCharacterSet() { return characterSet; } - public void setCharacters(short pCharacters) { - characters = pCharacters; + /** + * Ensure what is set does not go over 31 characters, and anything under 31 + * characters zero-fills. post-processing patch + * + * @param pCharacters an array of characters to set + */ + public void setCharacters(byte[] pCharacters) { + if (pCharacters.length >= characters.length) { + System.arraycopy(pCharacters, 0, characters, 0, characters.length); + } else { + int pCharactersLength = pCharacters.length; + System.arraycopy(pCharacters, 0, characters, 0, pCharactersLength); + for (int ix = pCharactersLength; ix < characters.length; ix++) { + // Ensure all zeros in unfilled fields + characters[ix] = 0; + } + } } - public short getCharacters() { + public byte[] getCharacters() { return characters; } public void marshal(DataOutputStream dos) { try { dos.writeByte((byte) characterSet); - dos.writeByte((byte) characters); + for (int idx = 0; idx < characters.length; idx++) { + dos.writeByte((byte) characters[idx]); + } // end of array marshaling } // end try catch (Exception e) { System.out.println(e); @@ -68,7 +87,9 @@ public void marshal(DataOutputStream dos) { public void unmarshal(DataInputStream dis) { try { characterSet = (short) dis.readUnsignedByte(); - characters = (short) dis.readUnsignedByte(); + for (int idx = 0; idx < characters.length; idx++) { + characters[idx] = (byte) dis.readUnsignedByte(); + } } // end try catch (Exception e) { System.out.println(e); @@ -86,7 +107,9 @@ public void unmarshal(DataInputStream dis) { */ public void marshal(java.nio.ByteBuffer buff) { buff.put((byte) characterSet); - buff.put((byte) characters); + for (int idx = 0; idx < characters.length; idx++) { + buff.put((byte) characters[idx]); + } // end of array marshaling } // end of marshal method /** @@ -99,7 +122,9 @@ public void marshal(java.nio.ByteBuffer buff) { */ public void unmarshal(java.nio.ByteBuffer buff) { characterSet = (short) (buff.get() & 0xFF); - characters = (short) (buff.get() & 0xFF); + for (int idx = 0; idx < characters.length; idx++) { + characters[idx] = buff.get(); + } // end of array unmarshaling } // end of unmarshal method @@ -143,8 +168,10 @@ public boolean equalsImpl(Object obj) { if (!(characterSet == rhs.characterSet)) { ivarsEqual = false; } - if (!(characters == rhs.characters)) { - ivarsEqual = false; + for (int idx = 0; idx < 31; idx++) { + if (!(characters[idx] == rhs.characters[idx])) { + ivarsEqual = false; + } } return ivarsEqual; diff --git a/src/main/java/edu/nps/moves/dis7/AggregateStatePdu.java b/src/main/java/edu/nps/moves/dis7/AggregateStatePdu.java new file mode 100644 index 0000000..f08e8c7 --- /dev/null +++ b/src/main/java/edu/nps/moves/dis7/AggregateStatePdu.java @@ -0,0 +1,636 @@ +package edu.nps.moves.dis7; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author fo + */ +public class AggregateStatePdu extends EntityManagementFamilyPdu implements Serializable { + + /** + * ID of aggregate + */ + protected AggregateIdentifier aggregateID = new AggregateIdentifier(); + + /** + * force ID + */ + protected short forceID; + + /** + * state of aggregate + */ + protected short aggregateState; + + /** + * Type of the aggregate + */ + protected AggregateType aggregateType = new AggregateType(); + + /** + * formation of aggregated entities + */ + protected long formation; + + /** + * marking for aggregate; first char is charset type, rest is char data + */ + protected AggregateMarking aggregateMarking = new AggregateMarking(); + + /** + * dimensions of bounding box for the aggregated entities, origin at the + * center of mass + */ + protected Vector3Float dimensions = new Vector3Float(); + + /** + * orientation of the bounding box + */ + protected Orientation orientation = new Orientation(); + + /** + * center of mass of the aggregation + */ + protected Vector3Double centerOfMass = new Vector3Double(); + + /** + * velocity of aggregation + */ + protected Vector3Float velocity = new Vector3Float(); + + /** + * number of aggregates + */ + protected int numberOfAggregateIds; + + /** + * number of entities + */ + protected int numberOfEntitiyIds; + + /** + * number of silent aggregate types + */ + protected int numberOfSilentAggregateSystems; + + /** + * number of silent entity types + */ + protected int numberOfSilentEntitySystems; + /** + * aggregates list + */ + protected List aggregateIDList = new ArrayList(); + /** + * entity ID list + */ + protected List entityIDList = new ArrayList(); + /** + * ^^^padding to put the start of the next list on a 32 bit boundary. This + * needs to be fixed + */ + protected short pad2; + + /** + * silent entity types + */ + protected List silentAggregateSystemList = new ArrayList(); + /** + * silent entity types + */ + protected List silentEntitySystemList = new ArrayList(); + + /** + * number of variable datum records + */ + protected long numberOfVariableDatumRecords; + + /** + * variableDatums + */ + protected List< VariableDatum> variableDatumList = new ArrayList< VariableDatum>(); + + public AggregateStatePdu() { + setPduType((short) 33); + } + + public int getMarshalledSize() { + int marshalSize = 0; + + marshalSize = marshalSize + super.getMarshalledSize(); + marshalSize = marshalSize + aggregateID.getMarshalledSize();//aggregateID + marshalSize = marshalSize + 1;//forceID + marshalSize = marshalSize + 1;//aggregateState + marshalSize = marshalSize + aggregateType.getMarshalledSize();//aggregateType + marshalSize = marshalSize + 4;//formation + marshalSize = marshalSize + aggregateMarking.getMarshalledSize();//aggregateMarking + marshalSize = marshalSize + dimensions.getMarshalledSize();//dimensions + marshalSize = marshalSize + orientation.getMarshalledSize();//orientation + marshalSize = marshalSize + centerOfMass.getMarshalledSize();//centerOfMass + marshalSize = marshalSize + velocity.getMarshalledSize();//velocity + marshalSize = marshalSize + 2; // numberOfDisAggregates + marshalSize = marshalSize + 2; // numberOfDisEntities + marshalSize = marshalSize + 2; // numberOfSilentAggregateTypes + marshalSize = marshalSize + 2; // numberOfSilentEntityTypes + for (int idx = 0; idx < aggregateIDList.size(); idx++) { + AggregateIdentifier listElement = aggregateIDList.get(idx); + marshalSize = marshalSize + listElement.getMarshalledSize(); + } + for (int idx = 0; idx < entityIDList.size(); idx++) { + EntityID listElement = entityIDList.get(idx); + marshalSize = marshalSize + listElement.getMarshalledSize(); + } + marshalSize = marshalSize + (getPad2Bits() / 8); // pad2 + for (int idx = 0; idx < silentAggregateSystemList.size(); idx++) { + SilentAggregateSystem listElement = silentAggregateSystemList.get(idx); + marshalSize = marshalSize + listElement.getMarshalledSize(); + } + for (int idx = 0; idx < silentEntitySystemList.size(); idx++) { + SilentEntitySystem listElement = silentEntitySystemList.get(idx); + marshalSize = marshalSize + listElement.getMarshalledSize(); + } + marshalSize = marshalSize + 4; // numberOfVariableDatumRecords + for (int idx = 0; idx < variableDatumList.size(); idx++) { + VariableDatum listElement = variableDatumList.get(idx); + marshalSize = marshalSize + listElement.getMarshalledSize(); + } + + return marshalSize; + } + + public short getPad2Bits() { + int val = 16 * ((aggregateIDList.size() + entityIDList.size()) % 2); + return (short) val; + } + + public AggregateIdentifier getAggregateID() { + return aggregateID; + } + + public void setAggregateID(AggregateIdentifier aggregateID) { + this.aggregateID = aggregateID; + } + + public short getForceID() { + return forceID; + } + + public void setForceID(short forceID) { + this.forceID = forceID; + } + + public short getAggregateState() { + return aggregateState; + } + + public void setAggregateState(short aggregateState) { + this.aggregateState = aggregateState; + } + + public AggregateType getAggregateType() { + return aggregateType; + } + + public void setAggregateType(AggregateType aggregateType) { + this.aggregateType = aggregateType; + } + + public long getFormation() { + return formation; + } + + public void setFormation(long formation) { + this.formation = formation; + } + + public AggregateMarking getAggregateMarking() { + return aggregateMarking; + } + + public void setAggregateMarking(AggregateMarking aggregateMarking) { + this.aggregateMarking = aggregateMarking; + } + + public Vector3Float getDimensions() { + return dimensions; + } + + public void setDimensions(Vector3Float dimensions) { + this.dimensions = dimensions; + } + + public Orientation getOrientation() { + return orientation; + } + + public void setOrientation(Orientation orientation) { + this.orientation = orientation; + } + + public Vector3Double getCenterOfMass() { + return centerOfMass; + } + + public void setCenterOfMass(Vector3Double centerOfMass) { + this.centerOfMass = centerOfMass; + } + + public Vector3Float getVelocity() { + return velocity; + } + + public void setVelocity(Vector3Float velocity) { + this.velocity = velocity; + } + + public List getAggregateIDList() { + return aggregateIDList; + } + + public void setAggregateIDList(List aggregateIDList) { + this.aggregateIDList = aggregateIDList; + } + + public List getEntityIDList() { + return entityIDList; + } + + public void setEntityIDList(List entityIDList) { + this.entityIDList = entityIDList; + } + + public short getPad2() { + return pad2; + } + + public void setPad2(short pad2) { + this.pad2 = pad2; + } + + public List getSilentAggregateSystemList() { + return silentAggregateSystemList; + } + + public void setSilentAggregateSystemList(List silentAggregateSystemList) { + this.silentAggregateSystemList = silentAggregateSystemList; + } + + public List getSilentEntitySystemList() { + return silentEntitySystemList; + } + + public void setSilentEntitySystemList(List silentEntitySystemList) { + this.silentEntitySystemList = silentEntitySystemList; + } + + public List getVariableDatumList() { + return variableDatumList; + } + + public void setVariableDatumList(List variableDatumList) { + this.variableDatumList = variableDatumList; + } + + public int getNumberOfAggregateIds() { + return numberOfAggregateIds; + } + + public int getNumberOfEntitiyIds() { + return numberOfEntitiyIds; + } + + public int getNumberOfSilentAggregateSystems() { + return numberOfSilentAggregateSystems; + } + + public int getNumberOfSilentEntitySystems() { + return numberOfSilentEntitySystems; + } + + public long getNumberOfVariableDatumRecords() { + return numberOfVariableDatumRecords; + } + + public void marshal(java.nio.ByteBuffer buff) { + super.marshal(buff); + aggregateID.marshal(buff); + buff.put((byte) forceID); + buff.put((byte) aggregateState); + aggregateType.marshal(buff); + buff.putInt((int) formation); + aggregateMarking.marshal(buff); + dimensions.marshal(buff); + orientation.marshal(buff); + centerOfMass.marshal(buff); + velocity.marshal(buff); + buff.putShort((short) aggregateIDList.size()); + buff.putShort((short) entityIDList.size()); + buff.putShort((short) silentAggregateSystemList.size()); + buff.putShort((short) silentEntitySystemList.size()); + for (int idx = 0; idx < aggregateIDList.size(); idx++) { + AggregateIdentifier aAggregateID = (AggregateIdentifier) aggregateIDList.get(idx); + aAggregateID.marshal(buff); + } // end of list marshalling + + for (int idx = 0; idx < entityIDList.size(); idx++) { + EntityID aEntityID = (EntityID) entityIDList.get(idx); + aEntityID.marshal(buff); + } // end of list marshalling + + if ((getPad2Bits() / 8) == 2) { + buff.putShort(pad2); + } + + for (int idx = 0; idx < silentAggregateSystemList.size(); idx++) { + SilentAggregateSystem aSilentAggregateSystem = (SilentAggregateSystem) silentAggregateSystemList.get(idx); + aSilentAggregateSystem.marshal(buff); + } // end of list marshalling + + for (int idx = 0; idx < silentEntitySystemList.size(); idx++) { + SilentEntitySystem aSilentEntitySystem = (SilentEntitySystem) silentEntitySystemList.get(idx); + aSilentEntitySystem.marshal(buff); + } // end of list marshalling + + buff.putInt((int) variableDatumList.size()); + + for (int idx = 0; idx < variableDatumList.size(); idx++) { + VariableDatum aVariableDatum = (VariableDatum) variableDatumList.get(idx); + aVariableDatum.marshal(buff); + } // end of list marshalling + + } // end of marshal method + + public void unmarshal(java.nio.ByteBuffer buff) { + super.unmarshal(buff); + aggregateID.unmarshal(buff); + forceID = (short) (buff.get() & 0xFF); + aggregateState = (short) (buff.get() & 0xFF); + aggregateType.unmarshal(buff); + formation = buff.getInt(); + aggregateMarking.unmarshal(buff); + dimensions.unmarshal(buff); + orientation.unmarshal(buff); + centerOfMass.unmarshal(buff); + velocity.unmarshal(buff); + numberOfAggregateIds = (int) (buff.getShort() & 0xFFFF); + numberOfEntitiyIds = (int) (buff.getShort() & 0xFFFF); + numberOfSilentAggregateSystems = (int) (buff.getShort() & 0xFFFF); + numberOfSilentEntitySystems = (int) (buff.getShort() & 0xFFFF); + for (int idx = 0; idx < numberOfAggregateIds; idx++) { + AggregateIdentifier anX = new AggregateIdentifier(); + anX.unmarshal(buff); + aggregateIDList.add(anX); + } + + for (int idx = 0; idx < numberOfEntitiyIds; idx++) { + EntityID anX = new EntityID(); + anX.unmarshal(buff); + entityIDList.add(anX); + } + //Determine if pad2 is present + int padBits = 16 * ((numberOfAggregateIds + numberOfEntitiyIds) % 2); + if ((padBits / 8) == 2) { + pad2 = buff.getShort(); + } + for (int idx = 0; idx < numberOfSilentAggregateSystems; idx++) { + SilentAggregateSystem anX = new SilentAggregateSystem(); + anX.unmarshal(buff); + silentAggregateSystemList.add(anX); + } + + for (int idx = 0; idx < numberOfSilentEntitySystems; idx++) { + SilentEntitySystem anX = new SilentEntitySystem(); + anX.unmarshal(buff); + silentEntitySystemList.add(anX); + } + + numberOfVariableDatumRecords = buff.getInt(); + for (int idx = 0; idx < numberOfVariableDatumRecords; idx++) { + VariableDatum anX = new VariableDatum(); + anX.unmarshal(buff); + variableDatumList.add(anX); + } + } // end of unmarshal method + + public void marshal(DataOutputStream dos) { + super.marshal(dos); + try { + aggregateID.marshal(dos); + dos.writeByte(forceID); + dos.writeByte(aggregateState); + aggregateType.marshal(dos); + dos.writeInt((int) formation); + aggregateMarking.marshal(dos); + dimensions.marshal(dos); + orientation.marshal(dos); + centerOfMass.marshal(dos); + velocity.marshal(dos); + dos.writeShort((short) aggregateIDList.size()); + dos.writeShort((short) entityIDList.size()); + dos.writeShort((short) silentAggregateSystemList.size()); + dos.writeShort((short) silentEntitySystemList.size()); + for (int idx = 0; idx < aggregateIDList.size(); idx++) { + AggregateIdentifier aAggregateID = (AggregateIdentifier) aggregateIDList.get(idx); + aAggregateID.marshal(dos); + } // end of list marshalling + + for (int idx = 0; idx < entityIDList.size(); idx++) { + EntityID aEntityID = (EntityID) entityIDList.get(idx); + aEntityID.marshal(dos); + } // end of list marshalling + + if ((getPad2Bits() / 8) == 2) { + dos.writeShort(pad2); + } + + for (int idx = 0; idx < silentAggregateSystemList.size(); idx++) { + SilentAggregateSystem aSilentAggregateSystem = (SilentAggregateSystem) silentAggregateSystemList.get(idx); + aSilentAggregateSystem.marshal(dos); + } // end of list marshalling + + for (int idx = 0; idx < silentEntitySystemList.size(); idx++) { + SilentEntitySystem aSilentEntitySystem = (SilentEntitySystem) silentEntitySystemList.get(idx); + aSilentEntitySystem.marshal(dos); + } // end of list marshalling + + dos.writeInt((int) variableDatumList.size()); + + for (int idx = 0; idx < variableDatumList.size(); idx++) { + VariableDatum aVariableDatum = (VariableDatum) variableDatumList.get(idx); + aVariableDatum.marshal(dos); + } // end of list marshalling + } // end try // end try + catch (Exception e) { + System.out.println(e); + } + } // end of marshal method + + public void unmarshal(DataInputStream dis) { + super.unmarshal(dis); + + try { + aggregateID.unmarshal(dis); + forceID = dis.readByte(); + aggregateState = dis.readByte(); + aggregateType.unmarshal(dis); + formation = dis.readInt(); + aggregateMarking.unmarshal(dis); + dimensions.unmarshal(dis); + orientation.unmarshal(dis); + centerOfMass.unmarshal(dis); + velocity.unmarshal(dis); + numberOfAggregateIds = (int) dis.readShort(); + numberOfEntitiyIds = (int) dis.readShort(); + numberOfSilentAggregateSystems = (int) dis.readShort(); + numberOfSilentEntitySystems = (int) dis.readShort(); + for (int idx = 0; idx < numberOfAggregateIds; idx++) { + AggregateIdentifier anX = new AggregateIdentifier(); + anX.unmarshal(dis); + aggregateIDList.add(anX); + } + + for (int idx = 0; idx < numberOfEntitiyIds; idx++) { + EntityID anX = new EntityID(); + anX.unmarshal(dis); + entityIDList.add(anX); + } + //Determine if pad2 is present + int padBits = 16 * ((numberOfAggregateIds + numberOfEntitiyIds) % 2); + if ((padBits / 8) == 2) { + pad2 = dis.readShort(); + } + for (int idx = 0; idx < numberOfSilentAggregateSystems; idx++) { + SilentAggregateSystem anX = new SilentAggregateSystem(); + anX.unmarshal(dis); + silentAggregateSystemList.add(anX); + } + + for (int idx = 0; idx < numberOfSilentEntitySystems; idx++) { + SilentEntitySystem anX = new SilentEntitySystem(); + anX.unmarshal(dis); + silentEntitySystemList.add(anX); + } + + numberOfVariableDatumRecords = dis.readInt(); + for (int idx = 0; idx < numberOfVariableDatumRecords; idx++) { + VariableDatum anX = new VariableDatum(); + anX.unmarshal(dis); + variableDatumList.add(anX); + } + } // end try + catch (Exception e) { + System.out.println(e); + } + } // end of unmarshal method + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (getClass() != obj.getClass()) { + return false; + } + + return equalsImpl(obj); + } + + @Override + public boolean equalsImpl(Object obj) { + boolean ivarsEqual = true; + + if (!(obj instanceof AggregateStatePdu)) { + return false; + } + + final AggregateStatePdu rhs = (AggregateStatePdu) obj; + + if (!(aggregateID.equals(rhs.aggregateID))) { + ivarsEqual = false; + } + if (!(forceID == rhs.forceID)) { + ivarsEqual = false; + } + if (!(aggregateState == rhs.aggregateState)) { + ivarsEqual = false; + } + if (!(aggregateType.equals(rhs.aggregateType))) { + ivarsEqual = false; + } + if (!(formation == rhs.formation)) { + ivarsEqual = false; + } + if (!(aggregateMarking.equals(rhs.aggregateMarking))) { + ivarsEqual = false; + } + if (!(dimensions.equals(rhs.dimensions))) { + ivarsEqual = false; + } + if (!(orientation.equals(rhs.orientation))) { + ivarsEqual = false; + } + if (!(centerOfMass.equals(rhs.centerOfMass))) { + ivarsEqual = false; + } + if (!(velocity.equals(rhs.velocity))) { + ivarsEqual = false; + } + if (!(numberOfAggregateIds == rhs.numberOfAggregateIds)) { + ivarsEqual = false; + } + if (!(numberOfEntitiyIds == rhs.numberOfEntitiyIds)) { + ivarsEqual = false; + } + if (!(numberOfSilentAggregateSystems == rhs.numberOfSilentAggregateSystems)) { + ivarsEqual = false; + } + if (!(numberOfSilentEntitySystems == rhs.numberOfSilentEntitySystems)) { + ivarsEqual = false; + } + for (int idx = 0; idx < aggregateIDList.size(); idx++) { + if (!(aggregateIDList.get(idx).equals(rhs.aggregateIDList.get(idx)))) { + ivarsEqual = false; + } + } + for (int idx = 0; idx < entityIDList.size(); idx++) { + if (!(entityIDList.get(idx).equals(rhs.entityIDList.get(idx)))) { + ivarsEqual = false; + } + } + if (!(pad2 == rhs.pad2)) { + ivarsEqual = false; + } + for (int idx = 0; idx < silentAggregateSystemList.size(); idx++) { + if (!(silentAggregateSystemList.get(idx).equals(rhs.silentAggregateSystemList.get(idx)))) { + ivarsEqual = false; + } + } + for (int idx = 0; idx < silentEntitySystemList.size(); idx++) { + if (!(silentEntitySystemList.get(idx).equals(rhs.silentEntitySystemList.get(idx)))) { + ivarsEqual = false; + } + } + if (!(numberOfVariableDatumRecords == rhs.numberOfVariableDatumRecords)) { + ivarsEqual = false; + } + + for (int idx = 0; idx < variableDatumList.size(); idx++) { + if (!(variableDatumList.get(idx).equals(rhs.variableDatumList.get(idx)))) { + ivarsEqual = false; + } + } + + return ivarsEqual && super.equalsImpl(rhs); + } +} diff --git a/src/main/java/edu/nps/moves/dis7/Orientation.java b/src/main/java/edu/nps/moves/dis7/Orientation.java new file mode 100644 index 0000000..8fc6558 --- /dev/null +++ b/src/main/java/edu/nps/moves/dis7/Orientation.java @@ -0,0 +1,159 @@ +package edu.nps.moves.dis7; + +import java.io.DataInputStream; +import java.io.DataOutputStream; + +/** + * + * @author fo + */ +public class Orientation { + + protected float psi; + + protected float theta; + + protected float phi; + + /** + * Constructor + */ + public Orientation() { + } + + public int getMarshalledSize() { + int marshalSize = 0; + + marshalSize = marshalSize + 4; // psi + marshalSize = marshalSize + 4; // theta + marshalSize = marshalSize + 4; // phi + + return marshalSize; + } + + public void setPsi(float pPsi) { + psi = pPsi; + } + + public float getPsi() { + return psi; + } + + public void setTheta(float pTheta) { + theta = pTheta; + } + + public float getTheta() { + return theta; + } + + public void setPhi(float pPhi) { + phi = pPhi; + } + + public float getPhi() { + return phi; + } + + /** + * Packs a Pdu into the ByteBuffer. + * + * @throws java.nio.BufferOverflowException if buff is too small + * @throws java.nio.ReadOnlyBufferException if buff is read only + * @see java.nio.ByteBuffer + * @param buff The ByteBuffer at the position to begin writing + * @since ?? + */ + public void marshal(java.nio.ByteBuffer buff) { + buff.putFloat((float) psi); + buff.putFloat((float) theta); + buff.putFloat((float) phi); + } // end of marshal method + + /** + * Unpacks a Pdu from the underlying data. + * + * @throws java.nio.BufferUnderflowException if buff is too small + * @see java.nio.ByteBuffer + * @param buff The ByteBuffer at the position to begin reading + * @since ?? + */ + public void unmarshal(java.nio.ByteBuffer buff) { + psi = buff.getFloat(); + theta = buff.getFloat(); + phi = buff.getFloat(); + } // end of unmarshal method + + public void marshal(DataOutputStream dos) { + + try { + dos.writeFloat(psi); + dos.writeFloat(theta); + dos.writeFloat(phi); + } // end try // end try + catch (Exception e) { + System.out.println(e); + } + } + + public void unmarshal(DataInputStream dis) { + try { + psi = dis.readFloat(); + theta = dis.readFloat(); + phi = dis.readFloat(); + } // end try + catch (Exception e) { + System.out.println(e); + } + } + + /* + * The equals method doesn't always work--mostly it works only on classes that consist only of primitives. Be careful. + */ + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (getClass() != obj.getClass()) { + return false; + } + + return equalsImpl(obj); + } + + /** + * Compare all fields that contribute to the state, ignoring transient and + * static fields, for this and the supplied object + * + * @param obj the object to compare to + * @return true if the objects are equal, false otherwise. + */ + public boolean equalsImpl(Object obj) { + boolean ivarsEqual = true; + + if (!(obj instanceof Orientation)) { + return false; + } + + final Orientation rhs = (Orientation) obj; + + if (!(psi == rhs.psi)) { + ivarsEqual = false; + } + if (!(theta == rhs.theta)) { + ivarsEqual = false; + } + if (!(phi == rhs.phi)) { + ivarsEqual = false; + } + + return ivarsEqual; + } +} diff --git a/src/main/java/edu/nps/moves/dis7/PduFactory.java b/src/main/java/edu/nps/moves/dis7/PduFactory.java index 4f34322..6aebf67 100644 --- a/src/main/java/edu/nps/moves/dis7/PduFactory.java +++ b/src/main/java/edu/nps/moves/dis7/PduFactory.java @@ -245,6 +245,9 @@ public Pdu createPdu(ByteBuffer buff) { case IFF_ATC_NAVAIDS: aPdu = new IFFPdu(); break; + case AGGREGATE_STATE: + aPdu = new AggregateStatePdu(); + break; default: this.logger.log(Level.INFO, "PDU not implemented. Type = " + pduType + "\n"); if (pduTypeEnum != null) { diff --git a/src/main/java/edu/nps/moves/dis7/SilentAggregateSystem.java b/src/main/java/edu/nps/moves/dis7/SilentAggregateSystem.java new file mode 100644 index 0000000..9dd0c3c --- /dev/null +++ b/src/main/java/edu/nps/moves/dis7/SilentAggregateSystem.java @@ -0,0 +1,114 @@ +package edu.nps.moves.dis7; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * + * @author fo + */ +public class SilentAggregateSystem { + // nr of silent aggregates of the following type + + protected short nrOfAggregates; + + // padding + protected short pad1 = 0xFF; + + //Aggregate type + protected AggregateType aggregateType = new AggregateType(); + + // Constructor + public SilentAggregateSystem() { + + } + + public int getMarshalledSize() { + int marshalSize = 0; + marshalSize = marshalSize + 2; // nrOfAggregates + marshalSize = marshalSize + 2; // paddingl + marshalSize = marshalSize + aggregateType.getMarshalledSize();//Aggregate type + + return marshalSize; + } + + public void setNrOfAggregates(short aNr) { + nrOfAggregates = aNr; + } + + public short getNrOfAggregates() { + return nrOfAggregates; + } + + public void setPadding(short aPad) { + pad1 = aPad; + } + + public short getPadding() { + return pad1; + } + + public AggregateType getAggregateType() { + return aggregateType; + } + + public void setAggregateType(AggregateType aggregateType) { + this.aggregateType = aggregateType; + } + + public void marshal(java.nio.ByteBuffer buff) { + buff.putShort((short) nrOfAggregates); + buff.putShort((short) pad1); + aggregateType.marshal(buff); + } // end of marshal method + + public void unmarshal(java.nio.ByteBuffer buff) { + nrOfAggregates = (short) (buff.getShort() & 0xFF); + pad1 = (short) (buff.getShort() & 0xFF); + aggregateType.unmarshal(buff); + } // end of unmarshal method + + public void marshal(DataOutputStream dos) { + try { + dos.writeShort((short) nrOfAggregates); + dos.writeShort((short) pad1); + aggregateType.marshal(dos); + } // end of marshal method + catch (IOException ex) { + System.out.println(ex); + } + } + + public void unmarshal(DataInputStream dis) { + try { + nrOfAggregates = (short) dis.readShort() ; + pad1 = (short) dis.readShort(); + aggregateType.unmarshal(dis); + } // end of unmarshal method + catch (IOException ex) { + System.out.println(ex); + } + } + + public boolean equalsImpl(Object obj) { + boolean ivarsEqual = true; + + if (!(obj instanceof SilentAggregateSystem)) { + return false; + } + + final SilentAggregateSystem rhs = (SilentAggregateSystem) obj; + + if (!(nrOfAggregates == rhs.nrOfAggregates)) { + ivarsEqual = false; + } + if (!(pad1 == rhs.pad1)) { + ivarsEqual = false; + } + if (!(aggregateType == rhs.aggregateType)) { + ivarsEqual = false; + } + return ivarsEqual; + } +} diff --git a/src/test/java/edu/nps/moves/dis7/AggregateStatePduTest.java b/src/test/java/edu/nps/moves/dis7/AggregateStatePduTest.java new file mode 100644 index 0000000..d385a60 --- /dev/null +++ b/src/test/java/edu/nps/moves/dis7/AggregateStatePduTest.java @@ -0,0 +1,199 @@ +package edu.nps.moves.dis7; + +import java.io.IOException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author fo + */ +public class AggregateStatePduTest { + + public AggregateStatePduTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + @Test + public void marshal() { + AggregateStatePdu dpdu = new AggregateStatePdu(); + + byte[] buffer = dpdu.marshal(); + + assertEquals(buffer.length, dpdu.getLength()); + } + + @Test + public void unmarshal() + throws IOException { + PduFactory factory = new PduFactory(); + Pdu pdu = factory.createPdu(edu.nps.moves.dis7.PduFileLoader.load("AggregateStatePdu.raw")); + + // Expected field values were determined from Wireshark: Decode As -> DIS. + // Header + assertEquals(7, pdu.getProtocolVersion()); + assertEquals(1, pdu.getExerciseID()); + assertEquals(33, pdu.getPduType()); + assertEquals(7, pdu.getProtocolFamily()); + assertEquals(508, pdu.getLength()); + assertEquals(0, pdu.getPadding()); + assertEquals(12, pdu.getPduStatus()); + + AggregateStatePdu espdu = (AggregateStatePdu) pdu; + + //AggregateID + assertEquals(1, espdu.getAggregateID().getSimulationAddress().getSite()); + assertEquals(1, espdu.getAggregateID().getSimulationAddress().getApplication()); + assertEquals(555, espdu.getAggregateID().getAggregateID()); + + //ForceID + assertEquals(1, espdu.getForceID()); + + //AggregateState + assertEquals(2, espdu.getAggregateState()); + + //AggregateType + assertEquals(1, espdu.getAggregateType().getAggregateKind()); + assertEquals(1, espdu.getAggregateType().getDomain()); + assertEquals(225, espdu.getAggregateType().getCountry()); + assertEquals(3, espdu.getAggregateType().getCategory()); + assertEquals(4, espdu.getAggregateType().getSubcategory()); + assertEquals(0, espdu.getAggregateType().getSpecificInfo()); + assertEquals(0, espdu.getAggregateType().getExtra()); + + //formation + assertEquals(4, espdu.getFormation()); + + //AggregateMarking + assertEquals(0, espdu.getAggregateMarking().getCharacterSet()); + assertEquals(31, espdu.getAggregateMarking().getCharacters().length); + String marking = "Demo-Aggregate"; + byte[] markingBytes = marking.getBytes(); + for (int i = 0; i < markingBytes.length; i++) { + assertEquals(markingBytes[i], espdu.getAggregateMarking().getCharacters()[i]); + } + + //Dimensions + assertEquals(1, espdu.getDimensions().getX(), 0.001); + assertEquals(1, espdu.getDimensions().getY(), 0.001); + assertEquals(1, espdu.getDimensions().getZ(), 0.001); + + //Orientation + assertEquals(3.1415927, espdu.getOrientation().getPsi(), 0.001); + assertEquals(-2.9628239, espdu.getOrientation().getTheta(), 0.001); + assertEquals(-0.58487105, espdu.getOrientation().getPhi(), 0.001); + + //CenterOfMass + assertEquals(3432718.14463848, espdu.getCenterOfMass().getX(), 0.001); + assertEquals(685871.683305762, espdu.getCenterOfMass().getY(), 0.001); + assertEquals(5314355.50692684, espdu.getCenterOfMass().getZ(), 0.001); + + //Velocity + assertEquals(0, espdu.getVelocity().getX(), 0.001); + assertEquals(0, espdu.getVelocity().getY(), 0.001); + assertEquals(0, espdu.getVelocity().getZ(), 0.001); + + //numerof... + assertEquals(2, espdu.getNumberOfAggregateIds()); + assertEquals(2, espdu.getNumberOfEntitiyIds()); + assertEquals(2, espdu.getNumberOfSilentAggregateSystems()); + assertEquals(1, espdu.getNumberOfSilentEntitySystems()); + + //AggregateId's + assertEquals(1, espdu.getAggregateIDList().get(0).getSimulationAddress().getSite()); + assertEquals(202, espdu.getAggregateIDList().get(0).getSimulationAddress().getApplication()); + assertEquals(1, espdu.getAggregateIDList().get(0).getAggregateID()); + + assertEquals(1, espdu.getAggregateIDList().get(1).getSimulationAddress().getSite()); + assertEquals(202, espdu.getAggregateIDList().get(1).getSimulationAddress().getApplication()); + assertEquals(3, espdu.getAggregateIDList().get(1).getAggregateID()); + + //EntityId's + assertEquals(1, espdu.getEntityIDList().get(0).getSiteID()); + assertEquals(202, espdu.getEntityIDList().get(0).getApplicationID()); + assertEquals(1, espdu.getEntityIDList().get(0).getEntityID()); + + assertEquals(1, espdu.getEntityIDList().get(1).getSiteID()); + assertEquals(202, espdu.getEntityIDList().get(1).getApplicationID()); + assertEquals(3, espdu.getEntityIDList().get(1).getEntityID()); + + //SilentAggregateSystems + assertEquals(1, espdu.getSilentAggregateSystemList().get(0).getAggregateType().getAggregateKind()); + assertEquals(1, espdu.getSilentAggregateSystemList().get(0).getAggregateType().getDomain()); + assertEquals(225, espdu.getSilentAggregateSystemList().get(0).getAggregateType().getCountry()); + assertEquals(3, espdu.getSilentAggregateSystemList().get(0).getAggregateType().getCategory()); + assertEquals(4, espdu.getSilentAggregateSystemList().get(0).getAggregateType().getSubcategory()); + assertEquals(0, espdu.getSilentAggregateSystemList().get(0).getAggregateType().getSpecificInfo()); + assertEquals(0, espdu.getSilentAggregateSystemList().get(0).getAggregateType().getExtra()); + assertEquals(1, espdu.getSilentAggregateSystemList().get(0).getNrOfAggregates()); + + assertEquals(1, espdu.getSilentAggregateSystemList().get(1).getAggregateType().getAggregateKind()); + assertEquals(1, espdu.getSilentAggregateSystemList().get(1).getAggregateType().getDomain()); + assertEquals(225, espdu.getSilentAggregateSystemList().get(1).getAggregateType().getCountry()); + assertEquals(3, espdu.getSilentAggregateSystemList().get(1).getAggregateType().getCategory()); + assertEquals(4, espdu.getSilentAggregateSystemList().get(1).getAggregateType().getSubcategory()); + assertEquals(0, espdu.getSilentAggregateSystemList().get(1).getAggregateType().getSpecificInfo()); + assertEquals(0, espdu.getSilentAggregateSystemList().get(1).getAggregateType().getExtra()); + assertEquals(1, espdu.getSilentAggregateSystemList().get(1).getNrOfAggregates()); + + //Vardatums + assertEquals(10000, espdu.getVariableDatumList().get(0).getVariableDatumID()); + byte[] byteArray = {0, 0, 0, 0x3}; + for (int i = 0; i < byteArray.length; i++) { + assertEquals(byteArray[i], espdu.getVariableDatumList().get(0).getVariableData()[i]); + } + + assertEquals(33000, espdu.getVariableDatumList().get(1).getVariableDatumID()); + byte[] byteArray1 = {0, (byte) 192, 0, 0}; + for (int i = 0; i < byteArray1.length; i++) { + assertEquals(byteArray1[i], espdu.getVariableDatumList().get(1).getVariableData()[i]); + } + + assertEquals(10000, espdu.getVariableDatumList().get(2).getVariableDatumID()); + byte[] byteArray2 = {0, 0, 0, 2, 0, 1, 11, (byte) 185, 0, 3, 0, 1, 11, (byte) 185, 0, 9}; + for (int i = 0; i < byteArray2.length; i++) { + assertEquals(byteArray2[i], espdu.getVariableDatumList().get(2).getVariableData()[i]); + } + + assertEquals(10000, espdu.getVariableDatumList().get(3).getVariableDatumID()); + byte[] byteArray3 = {0x00, 0x01, 0x0b, (byte) 0xb9, 0x00, 0x0d, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x0d, 0x01, 0x00, 0x06, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x02, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x20, 0x46, + 0x57, 0x2c, 0x20, 0x31, 0x20, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x66, 0x69, 0x72, 0x65, 0x2d, 0x61, 0x74, 0x2d, 0x77, 0x69, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x02, (byte) 0x45, (byte) 0xda, (byte) 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x4d, 0x61, 0x76, 0x65, 0x72, 0x69, 0x63, 0x6b, 0x20, 0x4d, 0x69, 0x73, 0x73, + (byte) 0x69, (byte) 0x6c, (byte) 0x65, 0x20, (byte) 0x4c, (byte) 0x61, (byte) 0x75, (byte) 0x6e, (byte) 0x63, (byte) 0x68, (byte) 0x65, (byte) 0x72, 0x46, (byte) 0x8c, (byte) 0xa0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x53, 0x69, + 0x64, 0x65, 0x77, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6c, 0x65, 0x20, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + for (int i = 0; i < byteArray3.length; i++) { + assertEquals(byteArray3[i], espdu.getVariableDatumList().get(3).getVariableData()[i]); + } + + assertEquals(10000, espdu.getVariableDatumList().get(4).getVariableDatumID()); + byte[] byteArray4 = {76, (byte) 105, (byte) 110, (byte) 101, 0}; + for (int i = 0; i < byteArray4.length; i++) { + assertEquals(byteArray4[i], espdu.getVariableDatumList().get(4).getVariableData()[i]); + } + + } +} diff --git a/src/test/resources/edu/nps/moves/dis7/AggregateStatePdu.raw b/src/test/resources/edu/nps/moves/dis7/AggregateStatePdu.raw new file mode 100644 index 0000000..b8632fd Binary files /dev/null and b/src/test/resources/edu/nps/moves/dis7/AggregateStatePdu.raw differ