This is an automated email from the ASF dual-hosted git repository.
ldywicki pushed a commit to branch sip
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/sip by this push:
new 3e0320929c First draft of sip protocol.
3e0320929c is described below
commit 3e0320929c09a490671e073515833eeba9bd2195
Author: Łukasz Dywicki <[email protected]>
AuthorDate: Mon Sep 22 23:13:42 2025 +0400
First draft of sip protocol.
Signed-off-by: Łukasz Dywicki <[email protected]>
---
plc4j/drivers/pom.xml | 1 +
plc4j/drivers/sip/pom.xml | 238 ++++++++++++++++
.../apache/plc4x/java/sip/readwrite/Constants.java | 173 ++++++++++++
.../apache/plc4x/java/sip/readwrite/SipPDU.java | 188 +++++++++++++
.../plc4x/java/sip/readwrite/SipRequestLine.java | 298 +++++++++++++++++++++
.../java/sip/readwrite/utils/StaticHelper.java | 103 +++++++
.../sip/readwrite/SipParserSerializerTest.java | 29 ++
.../java/spi/generation/WriteBufferXmlBased.java | 4 +-
protocols/pom.xml | 1 +
{plc4j/drivers => protocols/sip}/pom.xml | 49 ++--
.../org/apache/plc4x/protocol/sip/SipProtocol.java | 42 +++
...e.plc4x.plugins.codegenerator.protocol.Protocol | 19 ++
.../sip/src/main/resources/protocols/sip/sip.mspec | 29 ++
.../protocols/sip/ParserSerializerTestsuite.xml | 59 ++++
14 files changed, 1201 insertions(+), 32 deletions(-)
diff --git a/plc4j/drivers/pom.xml b/plc4j/drivers/pom.xml
index deb6a14ca0..6774b493f6 100644
--- a/plc4j/drivers/pom.xml
+++ b/plc4j/drivers/pom.xml
@@ -57,6 +57,7 @@
<module>profinet</module>
<module>profinet-ng</module>
<module>s7</module>
+ <module>sip</module>
<module>simulated</module>
<module>all</module>
</modules>
diff --git a/plc4j/drivers/sip/pom.xml b/plc4j/drivers/sip/pom.xml
new file mode 100644
index 0000000000..2e51565c54
--- /dev/null
+++ b/plc4j/drivers/sip/pom.xml
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4j-drivers</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>plc4j-driver-sip</artifactId>
+
+ <name>PLC4J: Driver: SIP</name>
+ <description>Implementation of a PLC4X driver for the SIP
protocol.</description>
+
+ <properties>
+
<project.build.outputTimestamp>2025-08-02T13:55:11Z</project.build.outputTimestamp>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.karaf.tooling</groupId>
+ <artifactId>karaf-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-feature-xml</id>
+ <phase>compile</phase>
+ <goals>
+ <!-- Generate the feature.xml -->
+ <goal>features-generate-descriptor</goal>
+ <!-- Check the feature.xml -->
+ <goal>verify</goal>
+ </goals>
+ <configuration>
+ <enableGeneration>true</enableGeneration>
+ <aggregateFeatures>true</aggregateFeatures>
+ </configuration>
+ </execution>
+ <execution>
+ <id>build-kar</id>
+ <phase>package</phase>
+ <goals>
+ <!--
+ Build a kar archive (Jar containing the feature.xml
+ as well as the module content and it's dependencies.
+ -->
+ <goal>kar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
+
<Bundle-Activator>org.apache.plc4x.java.osgi.DriverActivator</Bundle-Activator>
+
<Export-Service>org.apache.plc4x.java.api.PlcDriver,org.apache.plc4x.java.sip.readwrite.sipDriver
+ </Export-Service>
+ <Import-Package>
+ *
+ </Import-Package>
+ <SPI-consumer>*</SPI-consumer>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4j-api</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4j-spi</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4j-transport-udp</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.pcap4j</groupId>
+ <artifactId>pcap4j-core</artifactId>
+ <!-- Override the "provided" scope -->
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.pcap4j</groupId>
+ <artifactId>pcap4j-packetfactory-static</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-buffer</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-handler</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4j-utils-test-utils</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.skyscreamer</groupId>
+ <artifactId>jsonassert</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4x-protocols-sip</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ <classifier>tests</classifier>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>update-generated-code</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.plc4x.plugins</groupId>
+ <artifactId>plc4x-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-driver</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>generate-driver</goal>
+ </goals>
+ <configuration>
+ <protocolName>sip</protocolName>
+ <languageName>java</languageName>
+ <outputFlavor>read-write</outputFlavor>
+ <outputDir>src/main/generated</outputDir>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <configuration>
+ <usedDependencies combine.children="append">
+
<usedDependency>org.apache.plc4x:plc4x-code-generation-language-java</usedDependency>
+
<usedDependency>org.apache.plc4x:plc4x-protocols-sip</usedDependency>
+ </usedDependencies>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4x-code-generation-language-java</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ <!-- Scope is 'provided' as this way it's not shipped with the
driver -->
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4x-protocols-sip</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ <!-- Scope is 'provided' as this way it's not shipped with the
driver -->
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+
+</project>
diff --git
a/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/Constants.java
b/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/Constants.java
new file mode 100644
index 0000000000..a8e74b7992
--- /dev/null
+++
b/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/Constants.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.plc4x.java.sip.readwrite;
+
+import static org.apache.plc4x.java.spi.codegen.fields.FieldReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
+import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
+
+import java.io.*;
+import java.time.*;
+import java.util.*;
+import org.apache.plc4x.java.api.exceptions.*;
+import org.apache.plc4x.java.api.value.*;
+import org.apache.plc4x.java.spi.codegen.*;
+import org.apache.plc4x.java.spi.codegen.fields.*;
+import org.apache.plc4x.java.spi.codegen.io.*;
+import org.apache.plc4x.java.spi.generation.*;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+public class Constants implements Message {
+
+ // Constant values.
+ public static final Byte SPACE = 0x20;
+ public static final Byte COLON = 0x3a;
+ public static final Byte SLASH = 0x2f;
+ public static final Byte R = 0x0d;
+ public static final Byte N = 0x0a;
+
+ public Constants() {
+ super();
+ }
+
+ public byte getSPACE() {
+ return SPACE;
+ }
+
+ public byte getCOLON() {
+ return COLON;
+ }
+
+ public byte getSLASH() {
+ return SLASH;
+ }
+
+ public byte getR() {
+ return R;
+ }
+
+ public byte getN() {
+ return N;
+ }
+
+ public void serialize(WriteBuffer writeBuffer) throws SerializationException
{
+ PositionAware positionAware = writeBuffer;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+ writeBuffer.pushContext("Constants");
+
+ // Const Field (SPACE)
+ writeConstField("SPACE", SPACE, writeByte(writeBuffer, 8));
+
+ // Const Field (COLON)
+ writeConstField("COLON", COLON, writeByte(writeBuffer, 8));
+
+ // Const Field (SLASH)
+ writeConstField("SLASH", SLASH, writeByte(writeBuffer, 8));
+
+ // Const Field (R)
+ writeConstField("R", R, writeByte(writeBuffer, 8));
+
+ // Const Field (N)
+ writeConstField("N", N, writeByte(writeBuffer, 8));
+
+ writeBuffer.popContext("Constants");
+ }
+
+ @Override
+ public int getLengthInBytes() {
+ return (int) Math.ceil((float) getLengthInBits() / 8.0);
+ }
+
+ @Override
+ public int getLengthInBits() {
+ int lengthInBits = 0;
+ Constants _value = this;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+ // Const Field (SPACE)
+ lengthInBits += 8;
+
+ // Const Field (COLON)
+ lengthInBits += 8;
+
+ // Const Field (SLASH)
+ lengthInBits += 8;
+
+ // Const Field (R)
+ lengthInBits += 8;
+
+ // Const Field (N)
+ lengthInBits += 8;
+
+ return lengthInBits;
+ }
+
+ public static Constants staticParse(ReadBuffer readBuffer) throws
ParseException {
+ readBuffer.pullContext("Constants");
+ PositionAware positionAware = readBuffer;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+ byte SPACE = readConstField("SPACE", readByte(readBuffer, 8),
Constants.SPACE);
+
+ byte COLON = readConstField("COLON", readByte(readBuffer, 8),
Constants.COLON);
+
+ byte SLASH = readConstField("SLASH", readByte(readBuffer, 8),
Constants.SLASH);
+
+ byte R = readConstField("R", readByte(readBuffer, 8), Constants.R);
+
+ byte N = readConstField("N", readByte(readBuffer, 8), Constants.N);
+
+ readBuffer.closeContext("Constants");
+ // Create the instance
+ Constants _constants;
+ _constants = new Constants();
+ return _constants;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Constants)) {
+ return false;
+ }
+ Constants that = (Constants) o;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash();
+ }
+
+ @Override
+ public String toString() {
+ WriteBufferBoxBased writeBufferBoxBased = new WriteBufferBoxBased(true,
true);
+ try {
+ writeBufferBoxBased.writeSerializable(this);
+ } catch (SerializationException e) {
+ throw new RuntimeException(e);
+ }
+ return "\n" + writeBufferBoxBased.getBox().toString() + "\n";
+ }
+}
diff --git
a/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/SipPDU.java
b/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/SipPDU.java
new file mode 100644
index 0000000000..94635aa6c4
--- /dev/null
+++
b/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/SipPDU.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.plc4x.java.sip.readwrite;
+
+import static org.apache.plc4x.java.spi.codegen.fields.FieldReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
+import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
+
+import java.io.*;
+import java.time.*;
+import java.util.*;
+import org.apache.plc4x.java.api.exceptions.*;
+import org.apache.plc4x.java.api.value.*;
+import org.apache.plc4x.java.spi.codegen.*;
+import org.apache.plc4x.java.spi.codegen.fields.*;
+import org.apache.plc4x.java.spi.codegen.io.*;
+import org.apache.plc4x.java.spi.generation.*;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+public class SipPDU implements Message {
+
+ // Properties.
+ protected final SipRequestLine requestLine;
+ protected final byte[] data;
+
+ public SipPDU(SipRequestLine requestLine, byte[] data) {
+ super();
+ this.requestLine = requestLine;
+ this.data = data;
+ }
+
+ public SipRequestLine getRequestLine() {
+ return requestLine;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public void serialize(WriteBuffer writeBuffer) throws SerializationException
{
+ PositionAware positionAware = writeBuffer;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+ writeBuffer.pushContext("SipPDU");
+
+ // Simple Field (requestLine)
+ writeSimpleField(
+ "requestLine",
+ requestLine,
+ writeComplex(writeBuffer),
+ WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+ // Array Field (data)
+ writeByteArrayField(
+ "data",
+ data,
+ writeByteArray(writeBuffer, 8),
+ WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+ // Reserved Field (reserved)
+ writeReservedField(
+ "reserved",
+ (byte) Constants.R,
+ writeByte(writeBuffer, 8),
+ WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+ // Reserved Field (reserved)
+ writeReservedField(
+ "reserved",
+ (byte) Constants.N,
+ writeByte(writeBuffer, 8),
+ WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+ writeBuffer.popContext("SipPDU");
+ }
+
+ @Override
+ public int getLengthInBytes() {
+ return (int) Math.ceil((float) getLengthInBits() / 8.0);
+ }
+
+ @Override
+ public int getLengthInBits() {
+ int lengthInBits = 0;
+ SipPDU _value = this;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+ // Simple field (requestLine)
+ lengthInBits += requestLine.getLengthInBits();
+
+ // Array field
+ if (data != null) {
+ lengthInBits += 8 * data.length;
+ }
+
+ // Reserved Field (reserved)
+ lengthInBits += 8;
+
+ // Reserved Field (reserved)
+ lengthInBits += 8;
+
+ return lengthInBits;
+ }
+
+ public static SipPDU staticParse(ReadBuffer readBuffer, Integer len) throws
ParseException {
+ readBuffer.pullContext("SipPDU");
+ PositionAware positionAware = readBuffer;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+ SipRequestLine requestLine =
+ readSimpleField(
+ "requestLine",
+ readComplex(() -> SipRequestLine.staticParse(readBuffer),
readBuffer),
+ WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+ byte[] data =
+ readBuffer.readByteArray(
+ "data",
+ Math.toIntExact(((len) - (requestLine.getLengthInBytes())) - (2)),
+ WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+ Byte reservedField0 =
+ readReservedField(
+ "reserved",
+ readByte(readBuffer, 8),
+ (byte) Constants.R,
+ WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+ Byte reservedField1 =
+ readReservedField(
+ "reserved",
+ readByte(readBuffer, 8),
+ (byte) Constants.N,
+ WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+ readBuffer.closeContext("SipPDU");
+ // Create the instance
+ SipPDU _sipPDU;
+ _sipPDU = new SipPDU(requestLine, data);
+ return _sipPDU;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SipPDU)) {
+ return false;
+ }
+ SipPDU that = (SipPDU) o;
+ return (getRequestLine() == that.getRequestLine()) && (getData() ==
that.getData()) && true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getRequestLine(), getData());
+ }
+
+ @Override
+ public String toString() {
+ WriteBufferBoxBased writeBufferBoxBased = new WriteBufferBoxBased(true,
true);
+ try {
+ writeBufferBoxBased.writeSerializable(this);
+ } catch (SerializationException e) {
+ throw new RuntimeException(e);
+ }
+ return "\n" + writeBufferBoxBased.getBox().toString() + "\n";
+ }
+}
diff --git
a/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/SipRequestLine.java
b/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/SipRequestLine.java
new file mode 100644
index 0000000000..622e6d97cd
--- /dev/null
+++
b/plc4j/drivers/sip/src/main/generated/org/apache/plc4x/java/sip/readwrite/SipRequestLine.java
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.plc4x.java.sip.readwrite;
+
+import static org.apache.plc4x.java.spi.codegen.fields.FieldReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
+import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
+
+import java.io.*;
+import java.time.*;
+import java.util.*;
+import org.apache.plc4x.java.api.exceptions.*;
+import org.apache.plc4x.java.api.value.*;
+import org.apache.plc4x.java.spi.codegen.*;
+import org.apache.plc4x.java.spi.codegen.fields.*;
+import org.apache.plc4x.java.spi.codegen.io.*;
+import org.apache.plc4x.java.spi.generation.*;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+public class SipRequestLine implements Message {
+
+ // Properties.
+ protected final String method;
+ protected final String proto;
+ protected final String requestUri;
+ protected final String protocol;
+ protected final String version;
+
+ public SipRequestLine(
+ String method, String proto, String requestUri, String protocol, String
version) {
+ super();
+ this.method = method;
+ this.proto = proto;
+ this.requestUri = requestUri;
+ this.protocol = protocol;
+ this.version = version;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public String getProto() {
+ return proto;
+ }
+
+ public String getRequestUri() {
+ return requestUri;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void serialize(WriteBuffer writeBuffer) throws SerializationException
{
+ PositionAware positionAware = writeBuffer;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+ writeBuffer.pushContext("SipRequestLine");
+
+ // Manual Field (method)
+ writeManualField(
+ "method",
+ () ->
+
org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.writeStringTill(
+ writeBuffer, method),
+ writeBuffer);
+
+ // Reserved Field (reserved)
+ writeReservedField("reserved", (byte) Constants.SPACE,
writeByte(writeBuffer, 8));
+
+ // Manual Field (proto)
+ writeManualField(
+ "proto",
+ () ->
+
org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.writeStringTill(
+ writeBuffer, proto),
+ writeBuffer);
+
+ // Reserved Field (reserved)
+ writeReservedField("reserved", (byte) Constants.COLON,
writeByte(writeBuffer, 8));
+
+ // Manual Field (requestUri)
+ writeManualField(
+ "requestUri",
+ () ->
+
org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.writeStringTill(
+ writeBuffer, requestUri),
+ writeBuffer);
+
+ // Reserved Field (reserved)
+ writeReservedField("reserved", (byte) Constants.SPACE,
writeByte(writeBuffer, 8));
+
+ // Manual Field (protocol)
+ writeManualField(
+ "protocol",
+ () ->
+
org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.writeStringTill(
+ writeBuffer, protocol),
+ writeBuffer);
+
+ // Reserved Field (reserved)
+ writeReservedField("reserved", (byte) Constants.SLASH,
writeByte(writeBuffer, 8));
+
+ // Manual Field (version)
+ writeManualField(
+ "version",
+ () ->
+
org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.writeStringTill(
+ writeBuffer, version),
+ writeBuffer);
+
+ // Reserved Field (reserved)
+ writeReservedField("reserved", (byte) Constants.R, writeByte(writeBuffer,
8));
+
+ // Reserved Field (reserved)
+ writeReservedField("reserved", (byte) Constants.N, writeByte(writeBuffer,
8));
+
+ writeBuffer.popContext("SipRequestLine");
+ }
+
+ @Override
+ public int getLengthInBytes() {
+ return (int) Math.ceil((float) getLengthInBits() / 8.0);
+ }
+
+ @Override
+ public int getLengthInBits() {
+ int lengthInBits = 0;
+ SipRequestLine _value = this;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+ // Manual Field (method)
+ lengthInBits += (8) * (STR_LEN(method));
+
+ // Reserved Field (reserved)
+ lengthInBits += 8;
+
+ // Manual Field (proto)
+ lengthInBits += (8) * (STR_LEN(proto));
+
+ // Reserved Field (reserved)
+ lengthInBits += 8;
+
+ // Manual Field (requestUri)
+ lengthInBits += (8) * (STR_LEN(requestUri));
+
+ // Reserved Field (reserved)
+ lengthInBits += 8;
+
+ // Manual Field (protocol)
+ lengthInBits += (8) * (STR_LEN(protocol));
+
+ // Reserved Field (reserved)
+ lengthInBits += 8;
+
+ // Manual Field (version)
+ lengthInBits += (8) * (STR_LEN(version));
+
+ // Reserved Field (reserved)
+ lengthInBits += 8;
+
+ // Reserved Field (reserved)
+ lengthInBits += 8;
+
+ return lengthInBits;
+ }
+
+ public static SipRequestLine staticParse(ReadBuffer readBuffer) throws
ParseException {
+ readBuffer.pullContext("SipRequestLine");
+ PositionAware positionAware = readBuffer;
+ boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+ String method =
+ readManualField(
+ "method",
+ readBuffer,
+ () ->
+ (String)
+
(org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.readStringTill(
+ readBuffer, " ")));
+
+ Byte reservedField0 =
+ readReservedField("reserved", readByte(readBuffer, 8), (byte)
Constants.SPACE);
+
+ String proto =
+ readManualField(
+ "proto",
+ readBuffer,
+ () ->
+ (String)
+
(org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.readStringTill(
+ readBuffer, ":")));
+
+ Byte reservedField1 =
+ readReservedField("reserved", readByte(readBuffer, 8), (byte)
Constants.COLON);
+
+ String requestUri =
+ readManualField(
+ "requestUri",
+ readBuffer,
+ () ->
+ (String)
+
(org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.readStringTill(
+ readBuffer, " ")));
+
+ Byte reservedField2 =
+ readReservedField("reserved", readByte(readBuffer, 8), (byte)
Constants.SPACE);
+
+ String protocol =
+ readManualField(
+ "protocol",
+ readBuffer,
+ () ->
+ (String)
+
(org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.readStringTill(
+ readBuffer, "/")));
+
+ Byte reservedField3 =
+ readReservedField("reserved", readByte(readBuffer, 8), (byte)
Constants.SLASH);
+
+ String version =
+ readManualField(
+ "version",
+ readBuffer,
+ () ->
+ (String)
+
(org.apache.plc4x.java.sip.readwrite.utils.StaticHelper.readStringTill(
+ readBuffer, "\r\n")));
+
+ Byte reservedField4 =
+ readReservedField("reserved", readByte(readBuffer, 8), (byte)
Constants.R);
+
+ Byte reservedField5 =
+ readReservedField("reserved", readByte(readBuffer, 8), (byte)
Constants.N);
+
+ readBuffer.closeContext("SipRequestLine");
+ // Create the instance
+ SipRequestLine _sipRequestLine;
+ _sipRequestLine = new SipRequestLine(method, proto, requestUri, protocol,
version);
+ return _sipRequestLine;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SipRequestLine)) {
+ return false;
+ }
+ SipRequestLine that = (SipRequestLine) o;
+ return (getMethod() == that.getMethod())
+ && (getProto() == that.getProto())
+ && (getRequestUri() == that.getRequestUri())
+ && (getProtocol() == that.getProtocol())
+ && (getVersion() == that.getVersion())
+ && true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getMethod(), getProto(), getRequestUri(),
getProtocol(), getVersion());
+ }
+
+ @Override
+ public String toString() {
+ WriteBufferBoxBased writeBufferBoxBased = new WriteBufferBoxBased(true,
true);
+ try {
+ writeBufferBoxBased.writeSerializable(this);
+ } catch (SerializationException e) {
+ throw new RuntimeException(e);
+ }
+ return "\n" + writeBufferBoxBased.getBox().toString() + "\n";
+ }
+}
diff --git
a/plc4j/drivers/sip/src/main/java/org/apache/plc4x/java/sip/readwrite/utils/StaticHelper.java
b/plc4j/drivers/sip/src/main/java/org/apache/plc4x/java/sip/readwrite/utils/StaticHelper.java
new file mode 100644
index 0000000000..7478ac1e74
--- /dev/null
+++
b/plc4j/drivers/sip/src/main/java/org/apache/plc4x/java/sip/readwrite/utils/StaticHelper.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.plc4x.java.sip.readwrite.utils;
+
+import org.apache.plc4x.java.spi.generation.ParseException;
+import org.apache.plc4x.java.spi.generation.ReadBuffer;
+import org.apache.plc4x.java.spi.generation.SerializationException;
+import org.apache.plc4x.java.spi.generation.WriteBuffer;
+
+public class StaticHelper {
+
+ public static String asString(byte[] bytes) {
+ return new String(bytes);
+ }
+
+ public static boolean until(ReadBuffer readBuffer, String terminator)
throws ParseException {
+ int start = readBuffer.getPos();
+ StringBuilder buffer = new StringBuilder();
+ int length = terminator.length();
+ int retrieved = 0;
+ while (readBuffer.hasMore(8) && retrieved < length) {
+ buffer.append((char) readBuffer.readByte());
+ if (buffer.length() == length) {
+ if (buffer.toString().equals(terminator)) {
+ readBuffer.reset(start + length - 1);
+ return false;
+ }
+ break;
+ }
+ }
+
+ readBuffer.reset(start);
+ return true;
+ }
+
+ public static String readStringTill(ReadBuffer readBuffer, String
terminator) throws ParseException {
+ int start = readBuffer.getPos();
+ StringBuilder buffer = new StringBuilder();
+ int length = terminator.length();
+ while (readBuffer.hasMore(8)) {
+ buffer.append((char) readBuffer.readByte());
+ if (buffer.length() >= length) {
+ if (buffer.subSequence(buffer.length() - length,
buffer.length()).equals(terminator)) {
+ break;
+ }
+ }
+ }
+
+ int end = readBuffer.getPos();
+ readBuffer.reset(end - length);
+ if (start == end) {
+ return "";
+ }
+ return buffer.subSequence(0, buffer.length() - length).toString();
+ }
+
+ public static String readString(ReadBuffer readBuffer, String terminator)
throws ParseException {
+ int start = readBuffer.getPos();
+ StringBuilder buffer = new StringBuilder();
+ int length = terminator.length();
+ while (readBuffer.hasMore(8)) {
+ buffer.append((char) readBuffer.readByte());
+ if (buffer.length() >= length) {
+ if (buffer.subSequence(buffer.length() - length,
buffer.length()).equals(terminator)) {
+ break;
+ }
+ }
+ }
+
+ int end = readBuffer.getPos();
+ //readBuffer.reset(end - length);
+ if (start == end) {
+ return "";
+ }
+ //return buffer.subSequence(0, buffer.length() - length).toString();
+ return buffer.toString();
+ }
+
+ public static void writeString(WriteBuffer writeBuffer, String method/*,
String terminator*/) throws SerializationException {
+ writeBuffer.writeString(8 * method.length()/* + (terminator.length() *
8)*/ , method/* + terminator*/);
+ }
+
+ public static void writeStringTill(WriteBuffer writeBuffer, String method)
throws SerializationException {
+ writeBuffer.writeString(8 * method.length(), method);
+ }
+}
diff --git
a/plc4j/drivers/sip/src/test/java/org/apache/plc4x/java/sip/readwrite/SipParserSerializerTest.java
b/plc4j/drivers/sip/src/test/java/org/apache/plc4x/java/sip/readwrite/SipParserSerializerTest.java
new file mode 100644
index 0000000000..387a286cb0
--- /dev/null
+++
b/plc4j/drivers/sip/src/test/java/org/apache/plc4x/java/sip/readwrite/SipParserSerializerTest.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.plc4x.java.sip.readwrite;
+
+import org.apache.plc4x.test.parserserializer.ParserSerializerTestsuiteRunner;
+
+public class SipParserSerializerTest extends ParserSerializerTestsuiteRunner {
+
+ public SipParserSerializerTest() {
+ super("/protocols/sip/ParserSerializerTestsuite.xml");
+ }
+
+}
diff --git
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferXmlBased.java
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferXmlBased.java
index 47e3ab016c..84ec9aab06 100644
---
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferXmlBased.java
+++
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferXmlBased.java
@@ -204,8 +204,8 @@ public class WriteBufferXmlBased implements WriteBuffer,
BufferCommons {
@Override
public void writeString(String logicalName, int bitLength, String value,
WithWriterArgs... writerArgs) throws SerializationException {
String encoding = extractEncoding(writerArgs).orElse("UTF-8");
- String cleanedUpString =
StringUtils.trimToEmpty(value).replaceAll("[^\u0009\r\n\u0020-\uD7FF\uE000-\uFFFD\ud800\udc00-\udbff\udfff]",
"");
- createAndAppend(logicalName, rwStringKey, bitLength, cleanedUpString,
encoding, writerArgs);
+ //String cleanedUpString =
StringUtils.trimToEmpty(value).replaceAll("[^\u0009\r\n\u0020-\uD7FF\uE000-\uFFFD\ud800\udc00-\udbff\udfff]",
"");
+ createAndAppend(logicalName, rwStringKey, bitLength, value, encoding,
writerArgs);
move(bitLength);
}
diff --git a/protocols/pom.xml b/protocols/pom.xml
index 6baa7e1c28..6d802989e7 100644
--- a/protocols/pom.xml
+++ b/protocols/pom.xml
@@ -58,6 +58,7 @@
<module>profinet</module>
<module>s7</module>
<module>simulated</module>
+ <module>sip</module>
<module>socketcan</module>
<module>umas</module>
</modules>
diff --git a/plc4j/drivers/pom.xml b/protocols/sip/pom.xml
similarity index 60%
copy from plc4j/drivers/pom.xml
copy to protocols/sip/pom.xml
index deb6a14ca0..5fef82e40f 100644
--- a/plc4j/drivers/pom.xml
+++ b/protocols/sip/pom.xml
@@ -23,42 +23,31 @@
<parent>
<groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j</artifactId>
+ <artifactId>plc4x-protocols</artifactId>
<version>0.14.0-SNAPSHOT</version>
</parent>
- <artifactId>plc4j-drivers</artifactId>
- <packaging>pom</packaging>
+ <artifactId>plc4x-protocols-sip</artifactId>
- <name>PLC4J: Drivers</name>
- <description>Wrapper project for all PLC4J driver
implementations.</description>
+ <name>Protocols: SIP</name>
+ <description>Base protocol specifications for the SIP protocol</description>
<properties>
<project.build.outputTimestamp>2025-08-02T13:55:11Z</project.build.outputTimestamp>
</properties>
- <modules>
- <module>ab-eth</module>
- <module>ads</module>
- <module>bacnet</module>
- <module>c-bus</module>
- <module>can</module>
- <module>canopen</module>
- <module>ctrlx</module>
- <module>eip</module>
- <module>firmata</module>
- <module>iec-60870</module>
- <module>knxnetip</module>
- <module>mock</module>
- <module>open-protocol</module>
- <module>modbus</module>
- <module>opcua</module>
- <module>plc4x</module>
- <module>profinet</module>
- <module>profinet-ng</module>
- <module>s7</module>
- <module>simulated</module>
- <module>all</module>
- </modules>
-
-</project>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4x-code-generation-protocol-base-mspec</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git
a/protocols/sip/src/main/java/org/apache/plc4x/protocol/sip/SipProtocol.java
b/protocols/sip/src/main/java/org/apache/plc4x/protocol/sip/SipProtocol.java
new file mode 100644
index 0000000000..40fc89e99f
--- /dev/null
+++ b/protocols/sip/src/main/java/org/apache/plc4x/protocol/sip/SipProtocol.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.plc4x.protocol.sip;
+
+import
org.apache.plc4x.plugins.codegenerator.language.mspec.parser.MessageFormatParser;
+import
org.apache.plc4x.plugins.codegenerator.language.mspec.protocol.ProtocolHelpers;
+import
org.apache.plc4x.plugins.codegenerator.language.mspec.protocol.ValidatableTypeContext;
+import org.apache.plc4x.plugins.codegenerator.protocol.Protocol;
+import org.apache.plc4x.plugins.codegenerator.protocol.TypeContext;
+import
org.apache.plc4x.plugins.codegenerator.types.exceptions.GenerationException;
+
+public class SipProtocol implements Protocol, ProtocolHelpers {
+
+ @Override
+ public String getName() {
+ return "sip";
+ }
+
+ @Override
+ public TypeContext getTypeContext() throws GenerationException {
+ ValidatableTypeContext typeContext = new
MessageFormatParser().parse(getMspecStream());
+ typeContext.validate();
+ return typeContext;
+ }
+
+}
diff --git
a/protocols/sip/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol
b/protocols/sip/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol
new file mode 100644
index 0000000000..3a2e7a3183
--- /dev/null
+++
b/protocols/sip/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.plc4x.protocol.sip.SipProtocol
diff --git a/protocols/sip/src/main/resources/protocols/sip/sip.mspec
b/protocols/sip/src/main/resources/protocols/sip/sip.mspec
new file mode 100644
index 0000000000..926e900c91
--- /dev/null
+++ b/protocols/sip/src/main/resources/protocols/sip/sip.mspec
@@ -0,0 +1,29 @@
+[type SipPDU (uint 16 len) byteOrder='BIG_ENDIAN'
+ [simple SipRequestLine requestLine]
+ [array byte data count 'len - requestLine.lengthInBytes - 2']
+ [reserved byte 8 'Constants.R']
+ [reserved byte 8 'Constants.N']
+]
+
+[type Constants
+ [const byte SPACE 0x20]
+ [const byte COLON 0x3a]
+ [const byte SLASH 0x2f]
+ [const byte R 0x0d]
+ [const byte N 0x0a]
+]
+
+[type SipRequestLine
+ [manual vstring method 'STATIC_CALL("readStringTill", readBuffer, "
")' 'STATIC_CALL("writeStringTill", writeBuffer, method)' '8 *
STR_LEN(method)' ]
+ [reserved byte 8 'Constants.SPACE']
+ [manual vstring proto 'STATIC_CALL("readStringTill", readBuffer,
":")' 'STATIC_CALL("writeStringTill", writeBuffer, proto)' '8 *
STR_LEN(proto)' ]
+ [reserved byte 8 'Constants.COLON']
+ [manual vstring requestUri 'STATIC_CALL("readStringTill", readBuffer, "
")' 'STATIC_CALL("writeStringTill", writeBuffer, requestUri)' '8 *
STR_LEN(requestUri)' ]
+ [reserved byte 8 'Constants.SPACE']
+ [manual vstring protocol 'STATIC_CALL("readStringTill", readBuffer,
"/")' 'STATIC_CALL("writeStringTill", writeBuffer, protocol)' '8 *
STR_LEN(protocol)' ]
+ [reserved byte 8 'Constants.SLASH']
+ [manual vstring version 'STATIC_CALL("readStringTill", readBuffer,
"\r\n")' 'STATIC_CALL("writeStringTill", writeBuffer, version)' '8 *
STR_LEN(version)' ]
+ [reserved byte 8 'Constants.R']
+ [reserved byte 8 'Constants.N']
+]
+
diff --git
a/protocols/sip/src/test/resources/protocols/sip/ParserSerializerTestsuite.xml
b/protocols/sip/src/test/resources/protocols/sip/ParserSerializerTestsuite.xml
new file mode 100644
index 0000000000..b5833081f8
--- /dev/null
+++
b/protocols/sip/src/test/resources/protocols/sip/ParserSerializerTestsuite.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ -->
+<test:testsuite
xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd"
+ byteOrder="BIG_ENDIAN">
+
+ <name>SIP</name>
+
+ <protocolName>sip</protocolName>
+ <outputFlavor>read-write</outputFlavor>
+
+ <testcase>
+ <name>SIP Register</name>
+
<raw>5245474953544552207369703a7369702e6379626572636974792e646b205349502f322e300d0a5669613a205349502f322e302f554450203139322e3136382e312e323b6272616e63683d7a39684734624b6e703135313234383733372d34366561373135653139322e3136382e312e323b72706f72740d0a46726f6d3a203c7369703a766f693138303633407369702e6379626572636974792e646b3e3b7461673d393033646630610d0a546f3a203c7369703a766f693138303633407369702e6379626572636974792e646b3e0d0a43616c6c2d49443a203537383232323732392d343636356437373540353738323
[...]
+ <root-type>SipPDU</root-type>
+ <parser-arguments>
+ <len>467</len>
+ </parser-arguments>
+ <xml>
+ <SipPDU>
+ <requestLine>
+ <SipRequestLine>
+ <value dataType="string" bitLength="64"
encoding="UTF-8">REGISTER</value>
+ <reserved dataType="byte" bitLength="8">0x20</reserved>
+ <value dataType="string" bitLength="24"
encoding="UTF-8">sip</value>
+ <reserved dataType="byte" bitLength="8">0x3a</reserved>
+ <value dataType="string" bitLength="128"
encoding="UTF-8">sip.cybercity.dk</value>
+ <reserved dataType="byte" bitLength="8">0x20</reserved>
+ <value dataType="string" bitLength="24"
encoding="UTF-8">SIP</value>
+ <reserved dataType="byte" bitLength="8">0x2f</reserved>
+ <value dataType="string" bitLength="24"
encoding="UTF-8">2.0</value>
+ <reserved dataType="byte" bitLength="8">0x0d</reserved>
+ <reserved dataType="byte" bitLength="8">0x0a</reserved>
+ </SipRequestLine>
+ </requestLine>
+ <data dataType="byte"
bitLength="3408">0x5669613a205349502f322e302f554450203139322e3136382e312e323b6272616e63683d7a39684734624b6e703135313234383733372d34366561373135653139322e3136382e312e323b72706f72740d0a46726f6d3a203c7369703a766f693138303633407369702e6379626572636974792e646b3e3b7461673d393033646630610d0a546f3a203c7369703a766f693138303633407369702e6379626572636974792e646b3e0d0a43616c6c2d49443a203537383232323732392d3436363564373735403537383232323733322d34363635643737320d0a436f6e7
[...]
+ <reserved dataType="byte" bitLength="8">0x0d</reserved>
+ <reserved dataType="byte" bitLength="8">0x0a</reserved>
+ </SipPDU>
+ </xml>
+ </testcase>
+
+</test:testsuite>
\ No newline at end of file