diff --git a/modules/core/src/main/java/com/illposed/osc/OSCParser.java b/modules/core/src/main/java/com/illposed/osc/OSCParser.java index 07957cc5..e42f5a37 100644 --- a/modules/core/src/main/java/com/illposed/osc/OSCParser.java +++ b/modules/core/src/main/java/com/illposed/osc/OSCParser.java @@ -9,6 +9,8 @@ import com.illposed.osc.argument.ArgumentHandler; import com.illposed.osc.argument.handler.IntegerArgumentHandler; import com.illposed.osc.argument.handler.TimeTag64ArgumentHandler; +import com.illposed.osc.transport.NetworkProtocol; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.Buffer; @@ -223,7 +225,20 @@ private OSCBundle convertBundle(final ByteBuffer rawInput) throws OSCParseExcept * Assumes that the byte array is a message. * @return a message containing the data specified in the byte stream */ - private OSCMessage convertMessage(final ByteBuffer rawInput) throws OSCParseException { + private OSCMessage convertMessage(final ByteBuffer rawInputWithLength) throws OSCParseException { + + // remove the first four bytes, which is the frame length + // ideally we would use this to collect data from multiple incoming TCP packets, but for this will at least allow parsing to work for single packets + // we should only do this with TCP connections + ByteBuffer rawInput = null; + if ((properties.get("networkProtocol") == NetworkProtocol.TCP)&&(rawInputWithLength.limit() > 4)) { + rawInput = ByteBuffer.allocate(rawInputWithLength.limit() - 4); + for(int i = 4; i < rawInputWithLength.limit(); i++) { + rawInput.put(i - 4, rawInputWithLength.get(i)); + } + } else { + rawInput = rawInputWithLength; + } final String address = readString(rawInput); final CharSequence typeIdentifiers = readTypes(rawInput); diff --git a/modules/core/src/main/java/com/illposed/osc/OSCSerializer.java b/modules/core/src/main/java/com/illposed/osc/OSCSerializer.java index 1d775ebe..6d82922f 100644 --- a/modules/core/src/main/java/com/illposed/osc/OSCSerializer.java +++ b/modules/core/src/main/java/com/illposed/osc/OSCSerializer.java @@ -246,6 +246,28 @@ private void writeArguments(final OSCMessage message) throws OSCSerializeExcepti private void write(final OSCMessage message) throws OSCSerializeException { writeAddress(message); writeArguments(message); + if (properties.get("networkProtocol") == NetworkProtocol.TCP) { + writePLH(); + } + } + + /** + * Serializes a packet length header. Call this after writing the message and arguments. + * @throws OSCSerializeException if the message failed to serialize + */ + private void writePLH() throws OSCSerializeException { + byte[] rawOutput = output.toByteArray(); + int length = rawOutput.length; + byte[] newOutput = new byte[4 + length]; + ByteBuffer.wrap(newOutput).putInt(length); // add the length + ByteBuffer.wrap(newOutput, 4, length).put(rawOutput); // add the message content + + output.clear(); + output.put(newOutput); + + if (false) { // what to check here? + throw new OSCSerializeException("Error adding packet length header"); + } } /** diff --git a/modules/core/src/main/java/com/illposed/osc/OSCSerializerAndParserBuilder.java b/modules/core/src/main/java/com/illposed/osc/OSCSerializerAndParserBuilder.java index c3fac72b..cbd98ffa 100644 --- a/modules/core/src/main/java/com/illposed/osc/OSCSerializerAndParserBuilder.java +++ b/modules/core/src/main/java/com/illposed/osc/OSCSerializerAndParserBuilder.java @@ -29,6 +29,10 @@ public OSCSerializerAndParserBuilder() { this.usingDefaultHandlers = true; } + public void setNetworkProtocol(NetworkProtocol networkProtocol) { + this.properties.put("networkProtocol", networkProtocol); + } + // Public API @SuppressWarnings("WeakerAccess") public Map getIdentifierToTypeMapping() { diff --git a/modules/core/src/main/java/com/illposed/osc/transport/OSCPortInBuilder.java b/modules/core/src/main/java/com/illposed/osc/transport/OSCPortInBuilder.java index 3486419f..ac591b66 100644 --- a/modules/core/src/main/java/com/illposed/osc/transport/OSCPortInBuilder.java +++ b/modules/core/src/main/java/com/illposed/osc/transport/OSCPortInBuilder.java @@ -48,6 +48,7 @@ public OSCPortIn build() throws IOException { if (parserBuilder == null) { parserBuilder = new OSCSerializerAndParserBuilder(); + parserBuilder.setNetworkProtocol(networkProtocol); } if (packetListeners == null) { diff --git a/modules/core/src/main/java/com/illposed/osc/transport/OSCPortOutBuilder.java b/modules/core/src/main/java/com/illposed/osc/transport/OSCPortOutBuilder.java index 6792b3e2..1fcd8482 100644 --- a/modules/core/src/main/java/com/illposed/osc/transport/OSCPortOutBuilder.java +++ b/modules/core/src/main/java/com/illposed/osc/transport/OSCPortOutBuilder.java @@ -30,6 +30,7 @@ public OSCPortOut build() throws IOException { if (serializerBuilder == null) { serializerBuilder = new OSCSerializerAndParserBuilder(); + serializerBuilder.setNetworkProtocol(networkProtocol); } return new OSCPortOut(