You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2021/12/23 15:17:12 UTC

[plc4x] 02/02: feature: started implementing an mspec for the mqtt5 protocol.

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch feature/mqtt5_support
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 3a4682109439fdff04c0640f9e2979d4a54d4121
Author: cdutz <ch...@c-ware.de>
AuthorDate: Thu Dec 23 16:15:29 2021 +0100

    feature: started implementing an mspec for the mqtt5 protocol.
---
 protocols/mqtt/pom.xml                             |  43 ++
 .../apache/plc4x/protocol/mqtt/MqttProtocol.java   |  45 +++
 ...e.plc4x.plugins.codegenerator.protocol.Protocol |  19 +
 .../src/main/resources/protocols/mqtt/mqtt.mspec   | 438 +++++++++++++++++++++
 .../protocols/mqtt/ParserSerializerTestsuite.xml   |  81 ++++
 protocols/pom.xml                                  |   1 +
 sandbox/mqtt/mqtt-c/pom.xml                        | 319 +++++++++++++++
 sandbox/mqtt/mqtt-cs/pom.xml                       | 138 +++++++
 sandbox/mqtt/mqtt-go/pom.xml                       | 352 +++++++++++++++++
 sandbox/mqtt/mqtt-java/pom.xml                     | 116 ++++++
 .../mqtt/readwrite/MqttParserSerializerTest.java   |  29 ++
 sandbox/mqtt/pom.xml                               |  41 ++
 sandbox/pom.xml                                    |   1 +
 13 files changed, 1623 insertions(+)

diff --git a/protocols/mqtt/pom.xml b/protocols/mqtt/pom.xml
new file mode 100644
index 0000000..fb41ef5
--- /dev/null
+++ b/protocols/mqtt/pom.xml
@@ -0,0 +1,43 @@
+<?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
+
+      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.
+  -->
+<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>plc4x-protocols</artifactId>
+    <version>0.10.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>plc4x-protocols-mqtt</artifactId>
+
+  <name>Protocols: MQTT</name>
+  <description>Base protocol specifications for the MQTT protocol</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-code-generation-protocol-base-mspec</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/protocols/mqtt/src/main/java/org/apache/plc4x/protocol/mqtt/MqttProtocol.java b/protocols/mqtt/src/main/java/org/apache/plc4x/protocol/mqtt/MqttProtocol.java
new file mode 100644
index 0000000..8482f5d
--- /dev/null
+++ b/protocols/mqtt/src/main/java/org/apache/plc4x/protocol/mqtt/MqttProtocol.java
@@ -0,0 +1,45 @@
+/*
+ * 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.protocol.mqtt;
+
+import org.apache.plc4x.plugins.codegenerator.language.mspec.parser.MessageFormatParser;
+import org.apache.plc4x.plugins.codegenerator.protocol.Protocol;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
+import org.apache.plc4x.plugins.codegenerator.types.exceptions.GenerationException;
+
+import java.io.InputStream;
+import java.util.Map;
+
+public class MqttProtocol implements Protocol {
+
+    @Override
+    public String getName() {
+        return "mqtt";
+    }
+
+    @Override
+    public Map<String, TypeDefinition> getTypeDefinitions() throws GenerationException {
+        InputStream schemaInputStream = MqttProtocol.class.getResourceAsStream("/protocols/mqtt/mqtt.mspec");
+        if(schemaInputStream == null) {
+            throw new GenerationException("Error loading message-format schema for protocol '" + getName() + "'");
+        }
+        return new MessageFormatParser().parse(schemaInputStream);
+    }
+
+}
diff --git a/protocols/mqtt/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol b/protocols/mqtt/src/main/resources/META-INF/services/org.apache.plc4x.plugins.codegenerator.protocol.Protocol
new file mode 100644
index 0000000..287fe27
--- /dev/null
+++ b/protocols/mqtt/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
+#
+#     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.
+#
+org.apache.plc4x.protocol.mqtt.MqttProtocol
diff --git a/protocols/mqtt/src/main/resources/protocols/mqtt/mqtt.mspec b/protocols/mqtt/src/main/resources/protocols/mqtt/mqtt.mspec
new file mode 100644
index 0000000..94879f8
--- /dev/null
+++ b/protocols/mqtt/src/main/resources/protocols/mqtt/mqtt.mspec
@@ -0,0 +1,438 @@
+/*
+ * 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.
+ */
+
+[discriminatedType MQTT_ControlPacket    byteOrder='BIG_ENDIAN'
+    [discriminator MQTT_ControlPacketType packetType                                        ]
+    [abstract uint 8 remainingLength                                                        ]
+    [typeSwitch packetType
+        ['CONNECT' MQTT_ControlPacket_CONNECT
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                          ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            [simple   MQTT_String            protocolName                                   ]
+            [simple   uint 8                 protocolVersion                                ]
+            // Connect flags start
+            [simple   bit                    userNameFlagSet                                ]
+            [simple   bit                    passwordFlagSet                                ]
+            [simple   bit                    willRetainFlagSet                              ]
+            [simple   uint 2                 willQosLevel                                   ]
+            [simple   bit                    willFlagSet                                    ]
+            // Actually a session start ...
+            [simple   bit                    cleanStartFlagSet                              ]
+            [reserved bit                    'false'                                        ]
+            // Connect flags end
+            [simple   uint 16                keepAlive                                      ]
+
+            // Properties
+            [simple   uint 32                propertyLength        encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length 'propertyLength'         ]
+
+            // Payload
+            [simple   MQTT_String            clientId                                       ]
+            // TODO: If willFlagSet is true, the will properties come here (3.1.3.2)
+            // TODO: If willFlagSet is true, the will topic comes here (3.1.3.3)
+            // TODO: If willFlagSet is true, the will payload comes here (3.1.3.4)
+            // If userNameFlagSet, here comes the username. (String)
+            [optional MQTT_String            username       'userNameFlagSet'               ]
+            // If passwordFlagSet, here comes the password. (String)
+            [optional MQTT_String            password       'passwordFlagSet'               ]
+        ]
+        ['CONNACK' MQTT_ControlPacket_CONNACK
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                          ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            // Acknowledge flags start
+            [reserved uint 7                 '0x00'                                         ]
+            [simple   bit                    sessionPresentFlagSet                          ]
+            // Acknowledge flags end
+            [simple   MQTT_ReasonCode        reasonCode                                     ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+        ]
+        ['PUBLISH' MQTT_ControlPacket_PUBLISH
+            // Fixed Header
+            [simple   bit                    dup                                            ]
+            [simple   MQTT_QOS               qos                                            ]
+            [simple   bit                    retain                                         ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            [simple   MQTT_String            topicName                                      ]
+            [optional uint 16                packetIdentifier 'qos != MQTT_QOS.AT_MOST_ONCE']
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+
+            // Payload
+            [array    byte                   payload      count 'remainingLength - curPos'  ]
+        ]
+        // Used if QOS = 1
+        ['PUBACK' MQTT_ControlPacket_PUBACK
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                          ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            [simple   uint 16                packetIdentifier                               ]
+            [optional MQTT_ReasonCode        reasonCode     'remainingLength - curPos < 3'  ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+        ]
+        // Used if QOS = 2
+        ['PUBREC' MQTT_ControlPacket_PUBREC
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                          ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            [simple   uint 16                packetIdentifier                               ]
+            [optional MQTT_ReasonCode        reasonCode     'remainingLength - curPos < 3'  ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+        ]
+        ['PUBREL' MQTT_ControlPacket_PUBREL
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                          ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            [simple   uint 16                packetIdentifier                               ]
+            [optional MQTT_ReasonCode        reasonCode     'remainingLength - curPos < 3'  ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+        ]
+        ['PUBCOMP' MQTT_ControlPacket_PUBCOMP
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                          ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            [simple   uint 16                packetIdentifier                               ]
+            [optional MQTT_ReasonCode        reasonCode     'remainingLength - curPos < 3'  ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+        ]
+        ['SUBSCRIBE' MQTT_ControlPacket_SUBSCRIBE
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                          ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            [simple   uint 16                packetIdentifier                               ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+
+            // Payload
+            [array    Filter                 filters      count 'remainingLength - curPos'  ]
+        ]
+        ['SUBACK' MQTT_ControlPacket_SUBACK
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                          ]
+            [simple   uint 8                 remainingLength                                ]
+            // Variable Header
+            [simple   uint 16                packetIdentifier                               ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+
+            // Payload
+            [array    MQTT_ReasonCode        results        count 'remainingLength - curPos'    ]
+        ]
+        ['UNSUBSCRIBE' MQTT_ControlPacket_UNSUBSCRIBE
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                              ]
+            [simple   uint 8                 remainingLength                                    ]
+            // Variable Header
+            [simple   uint 16                packetIdentifier                                   ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+
+            // Payload
+            [array    MQTT_String            filters        count 'remainingLength - curPos'    ]
+        ]
+        ['UNSUBACK' MQTT_ControlPacket_UNSUBACK
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                              ]
+            [simple   uint 8                 remainingLength                                    ]
+            // Variable Header
+            [simple   uint 16                packetIdentifier                                   ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+
+            // Payload
+            [array    MQTT_ReasonCode        results        count 'remainingLength - curPos'    ]
+        ]
+        ['PINGREQ' MQTT_ControlPacket_PINGREQ
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                              ]
+            [simple   uint 8                 remainingLength                                    ]
+        ]
+        ['PINGRESP' MQTT_ControlPacket_PINGRESP
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                              ]
+            [simple   uint 8                 remainingLength                                    ]
+        ]
+        ['DISCONNECT' MQTT_ControlPacket_DISCONNECT
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                              ]
+            [simple   uint 8                 remainingLength                                    ]
+            // Variable Header
+            [simple   MQTT_ReasonCode        reason                                             ]
+        ]
+        ['AUTH' MQTT_ControlPacket_AUTH
+            // Fixed Header
+            [reserved uint 4                 '0x0'                                              ]
+            [simple   uint 8                 remainingLength                                    ]
+            // Variable Header
+            [simple   MQTT_ReasonCode        reason                                             ]
+
+            // Properties
+            [optional uint 32                propertyLength 'remainingLength - curPos < 4'       encoding='"varLenUint32"']
+            [array    MQTT_Property          properties     length '(propertyLength != null) ? propertyLength : 0']
+        ]
+    ]
+]
+
+[discriminatedType MQTT_Property
+    [simple MQTT_PropertyType propertyType]
+    [typeSwitch propertyType
+        ['PAYLOAD_FORMAT_INDICATOR'          MQTT_Property_PAYLOAD_FORMAT_INDICATOR
+            [simple uint 8                   value                              ]
+        ]
+        ['MESSAGE_EXPIRY_INTERVAL'           MQTT_Property_MESSAGE_EXPIRY_INTERVAL
+            [simple uint 32                  value                              ]
+        ]
+        ['CONTENT_TYPE'                      MQTT_Property_CONTENT_TYPE
+            [simple   MQTT_String            value                              ]
+        ]
+        ['RESPONSE_TOPIC'                    MQTT_Property_RESPONSE_TOPIC
+            [simple   MQTT_String            value                              ]
+        ]
+        ['CORRELATION_DATA'                  MQTT_Property_CORRELATION_DATA
+            // TODO: Find out what "Binary Data" means ...
+        ]
+        ['SUBSCRIPTION_IDENTIFIER'           MQTT_Property_SUBSCRIPTION_IDENTIFIER
+            [simple uint 32                  value     encoding='"varLenUint32"']
+        ]
+        ['SESSION_EXPIRY_INTERVAL'           MQTT_Property_EXPIRY_INTERVAL
+            [simple uint 32                  value                              ]
+        ]
+        ['ASSIGNED_CLIENT_IDENTIFIER'        MQTT_Property_ASSIGNED_CLIENT_IDENTIFIER
+            [simple   MQTT_String            value                              ]
+        ]
+        ['SERVER_KEEP_ALIVE'                 MQTT_Property_SERVER_KEEP_ALIVE
+            [simple uint 16                  value                              ]
+        ]
+        ['AUTHENTICATION_METHOD'             MQTT_Property_AUTHENTICATION_METHOD
+            [simple   MQTT_String            value                              ]
+        ]
+        ['AUTHENTICATION_DATA'               MQTT_Property_AUTHENTICATION_DATA
+            // TODO: Find out what "Binary Data" means ...
+        ]
+        ['REQUEST_PROBLEM_INFORMATION'       MQTT_Property_REQUEST_PROBLEM_INFORMATION
+            // TODO: Probably an enum
+            [simple uint 8                   value                              ]
+        ]
+        ['WILL_DELAY_INTERVAL'               MQTT_Property_WILL_DELAY_INTERVAL
+            [simple uint 32                  value                              ]
+        ]
+        ['REQUEST_RESPONSE_INFORMATION'      MQTT_Property_REQUEST_RESPONSE_INFORMATION
+            // TODO: Probably an enum
+            [simple uint 8                   value                              ]
+        ]
+        ['RESPONSE_INFORMATION'              MQTT_Property_RESPONSE_INFORMATION
+            [simple   MQTT_String            value                              ]
+        ]
+        ['SERVER_REFERENCE'                  MQTT_Property_SERVER_REFERENCE
+            [simple   MQTT_String            value                              ]
+        ]
+        ['REASON_STRING'                     MQTT_Property_REASON_STRING
+            [simple   MQTT_String            value                              ]
+        ]
+        ['RECEIVE_MAXIMUM'                   MQTT_Property_RECEIVE_MAXIMUM
+            [simple uint 16                  value                              ]
+        ]
+        ['TOPIC_ALIAS_MAXIMUM'               MQTT_Property_TOPIC_ALIAS_MAXIMUM
+            [simple uint 16                  value                              ]
+        ]
+        ['TOPIC_ALIAS'                       MQTT_Property_TOPIC_ALIAS
+            [simple uint 16                  value                              ]
+        ]
+        ['MAXIMUM_QOS'                       MQTT_Property_MAXIMUM_QOS
+            [simple uint 8                   value                              ]
+        ]
+        ['RETAIN_AVAILABLE'                  MQTT_Property_RETAIN_AVAILABLE
+            [simple uint 8                   value                              ]
+        ]
+        ['USER_PROPERTY'                     MQTT_Property_USER_PROPERTY
+            [simple   MQTT_String            name                               ]
+            [simple   MQTT_String            value                              ]
+        ]
+        ['MAXIMUM_PACKET_SIZE'               MQTT_Property_MAXIMUM_PACKET_SIZE
+            [simple uint 32                  value                              ]
+        ]
+        ['WILDCARD_SUBSCRIPTION_AVAILABLE'   MQTT_Property_WILDCARD_SUBSCRIPTION_AVAILABLE
+            [simple uint 8                   value                              ]
+        ]
+        ['SUBSCRIPTION_IDENTIFIER_AVAILABLE' MQTT_Property_SUBSCRIPTION_IDENTIFIER_AVAILABLE
+            [simple uint 8                   value                              ]
+        ]
+        ['SHARED_SUBSCRIPTION_AVAILABLE'     MQTT_Property_SHARED_SUBSCRIPTION_AVAILABLE
+            [simple uint 8                   value                              ]
+        ]
+    ]
+]
+
+[type Filter
+    [simple   MQTT_String         filter        ]
+    // Subscription Options Start
+    [reserved uint 2              '0x0'         ]
+    // Don't forward to clients with a client id equal to the sending one
+    [simple   MQTT_RetainHandling retainHandling]
+    [simple   bit                 retain        ]
+    [simple   bit                 noLocal       ]
+    [simple   MQTT_QOS            maxQos        ]
+    // Subscription Options End
+]
+
+[type MQTT_String
+    [implicit uint 16                stringLength 'STR_LEN(value)']
+    [simple   vstring 'stringLength * 8' value                        ]
+]
+
+[enum uint 4 MQTT_ControlPacketType
+    ['0x0' RESERVED   ]
+    ['0x1' CONNECT    ]
+    ['0x2' CONNACK    ]
+    ['0x3' PUBLISH    ]
+    ['0x4' PUBACK     ]
+    ['0x5' PUBREC     ]
+    ['0x6' PUBREL     ]
+    ['0x7' PUBCOMP    ]
+    ['0x8' SUBSCRIBE  ]
+    ['0x9' SUBACK     ]
+    ['0xA' UNSUBSCRIBE]
+    ['0xB' UNSUBACK   ]
+    ['0xC' PINGREQ    ]
+    ['0xD' PINGRESP   ]
+    ['0xE' DISCONNECT ]
+    ['0xF' AUTH       ]
+]
+
+[enum uint 8 MQTT_PropertyType
+    ['0x01' PAYLOAD_FORMAT_INDICATOR         ]
+    ['0x02' MESSAGE_EXPIRY_INTERVAL          ]
+    ['0x03' CONTENT_TYPE                     ]
+    ['0x08' RESPONSE_TOPIC                   ]
+    ['0x09' CORRELATION_DATA                 ]
+    ['0x0B' SUBSCRIPTION_IDENTIFIER          ]
+    ['0x11' SESSION_EXPIRY_INTERVAL          ]
+    ['0x12' ASSIGNED_CLIENT_IDENTIFIER       ]
+    ['0x13' SERVER_KEEP_ALIVE                ]
+    ['0x15' AUTHENTICATION_METHOD            ]
+    ['0x16' AUTHENTICATION_DATA              ]
+    ['0x17' REQUEST_PROBLEM_INFORMATION      ]
+    ['0x18' WILL_DELAY_INTERVAL              ]
+    ['0x19' REQUEST_RESPONSE_INFORMATION     ]
+    ['0x1A' RESPONSE_INFORMATION             ]
+    ['0x1C' SERVER_REFERENCE                 ]
+    ['0x1F' REASON_STRING                    ]
+    ['0x21' RECEIVE_MAXIMUM                  ]
+    ['0x22' TOPIC_ALIAS_MAXIMUM              ]
+    ['0x23' TOPIC_ALIAS                      ]
+    ['0x24' MAXIMUM_QOS                      ]
+    ['0x25' RETAIN_AVAILABLE                 ]
+    ['0x26' USER_PROPERTY                    ]
+    ['0x27' MAXIMUM_PACKET_SIZE              ]
+    ['0x28' WILDCARD_SUBSCRIPTION_AVAILABLE  ]
+    ['0x29' SUBSCRIPTION_IDENTIFIER_AVAILABLE]
+    ['0x2A' SHARED_SUBSCRIPTION_AVAILABLE    ]
+]
+
+[enum uint 8 MQTT_ReasonCode                       (bit connackResponse, bit pubackPubrecResponse, bit pubrelPubcompResponse, bit subackResponse, bit unsubackResponse, bit disconnectReason, bit authReason)
+    ['0X00' SUCCESS                                ['true'             , 'true'                  , 'true'                   , 'true'            , 'true'              , 'true'              , 'true'       ]]
+    ['0X01' GRANTED_QOS_1                          ['false'            , 'false'                 , 'false'                  , 'true'            , 'false'             , 'false'             , 'false'      ]]
+    ['0X02' GRANTED_QOS_2                          ['false'            , 'false'                 , 'false'                  , 'true'            , 'false'             , 'false'             , 'false'      ]]
+    ['0X04' DISCONNECT_WITH_WILL_MESSAGE           ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0x10' NO_MATCHING_SUBSCRIBERS                ['false'            , 'true'                  , 'false'                  , 'false'           , 'false'             , 'false'             , 'false'      ]]
+    ['0x11' NO_SUBSCRIPTION_EXISTED                ['false'            , 'false'                 , 'false'                  , 'false'           , 'true'              , 'false'             , 'false'      ]]
+    ['0X18' CONTINUE_AUTHENTICATION                ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'false'             , 'true'       ]]
+    ['0X19' RE_AUTHENTICATE                        ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'false'             , 'true'       ]]
+    ['0X80' UNSPECIFIED_ERROR                      ['true'             , 'true'                  , 'false'                  , 'true'            , 'true'              , 'true'              , 'false'      ]]
+    ['0X81' MALFORMED_PACKET                       ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X82' PROTOCOL_ERROR                         ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X83' IMPLEMENTATION_SPECIFIC_ERROR          ['true'             , 'true'                  , 'false'                  , 'true'            , 'true'              , 'true'              , 'false'      ]]
+    ['0X84' UNSUPPORTED_PROTOCOL_VERSION           ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'false'             , 'false'      ]]
+    ['0X85' CLIENT_IDENTIFIER_NOT_VALID            ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'false'             , 'false'      ]]
+    ['0X86' BAD_USER_NAME_OR_PASSWORD              ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'false'             , 'false'      ]]
+    ['0X87' NOT_AUTHORIZED                         ['true'             , 'true'                  , 'false'                  , 'true'            , 'true'              , 'true'              , 'false'      ]]
+    ['0X88' SERVER_UNAVAILABLE                     ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'false'             , 'false'      ]]
+    ['0X89' SERVER_BUSY                            ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X8A' BANNED                                 ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'false'             , 'false'      ]]
+    ['0X8B' SERVER_SHUTTING_DOWN                   ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X8C' BAD_AUTHENTICATION_METHOD              ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'false'             , 'false'      ]]
+    ['0X8D' KEEP_ALIVE_TIMEOUT                     ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X8E' SESSION_TAKEN_OVER                     ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X8F' TOPIC_FILTER_INVALID                   ['false'            , 'false'                 , 'false'                  , 'true'            , 'true'              , 'true'              , 'false'      ]]
+    ['0X90' TOPIC_NAME_INVALID                     ['true'             , 'true'                  , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X91' PACKET_IDENTIFIER_IN_USE               ['false'            , 'true'                  , 'false'                  , 'true'            , 'true'              , 'false'             , 'false'      ]]
+    ['0X92' PACKET_IDENTIFIER_NOT_FOUND            ['false'            , 'false'                 , 'true'                   , 'false'           , 'false'             , 'false'             , 'false'      ]]
+    ['0X93' RECEIVE_MAXIMUM_EXCEEDED               ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X94' TOPIC_ALIAS_INVALID                    ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X95' PACKET_TOO_LARGE                       ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X96' MESSAGE_RATE_TO_HIGH                   ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X97' QUOTA_EXCEEDED                         ['true'             , 'true'                  , 'false'                  , 'true'            , 'false'             , 'true'              , 'false'      ]]
+    ['0X98' ADMINISTRATIVE_ACTION                  ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X99' PAYLOAD_FORMAT_INVALID                 ['true'             , 'true'                  , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X9A' RETAIN_NOT_SUPPORTED                   ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X9B' QOS_NOT_SUPPORTED                      ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X9C' USE_ANOTHER_SERVER                     ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X9D' SERVER_MOVED                           ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0X9E' SHARED_SUBSCRIPTIONS_NOT_SUPPORTED     ['false'            , 'false'                 , 'false'                  , 'true'            , 'false'             , 'true'              , 'false'      ]]
+    ['0X9F' CONNECTION_RATE_EXCEEDED               ['true'             , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0XA0' MAXIMUM_CONNECT_TIME                   ['false'            , 'false'                 , 'false'                  , 'false'           , 'false'             , 'true'              , 'false'      ]]
+    ['0XA1' SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED ['false'            , 'false'                 , 'false'                  , 'true'            , 'false'             , 'true'              , 'false'      ]]
+    ['0XA2' WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED   ['false'            , 'false'                 , 'false'                  , 'true'            , 'false'             , 'true'              , 'false'      ]]
+]
+
+[enum uint 2 MQTT_QOS
+    ['0x0' AT_MOST_ONCE ]
+    ['0x1' AT_LEAST_ONCE]
+    ['0x2' EXACTLY_ONCE ]
+]
+
+[enum uint 2 MQTT_RetainHandling
+    ['0x0' SEND_RETAINED_MESSAGES_AT_THE_TIME_OF_THE_SUBSCRIBE                                  ]
+    ['0x1' SEND_RETAINED_MESSAGES_AT_SUBSCRIBE_ONLY_IF_THE_SUBSCRIPTION_DOES_NOT_CURRENTLY_EXIST]
+    ['0x2' DO_NOT_SEND_RETAINED_MESSAGES_AT_THE_TIME_OF_SUBSCRIBE                               ]
+]
diff --git a/protocols/mqtt/src/test/resources/protocols/mqtt/ParserSerializerTestsuite.xml b/protocols/mqtt/src/test/resources/protocols/mqtt/ParserSerializerTestsuite.xml
new file mode 100644
index 0000000..1719da4
--- /dev/null
+++ b/protocols/mqtt/src/test/resources/protocols/mqtt/ParserSerializerTestsuite.xml
@@ -0,0 +1,81 @@
+<?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
+
+      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.
+  -->
+<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd"
+                byteOrder="BIG_ENDIAN">
+
+  <name>MQTT5</name>
+
+  <protocolName>mqtt</protocolName>
+  <outputFlavor>read-write</outputFlavor>
+
+  <testcase>
+    <name>MQTT Connection Request</name>
+    <raw>101d00044d51545405c200050000066c776d71747400037472790003747279</raw>
+    <root-type>MQTT_ControlPacket</root-type>
+    <xml>
+      <MQTT_ControlPacket>
+        <packetType>
+          <MQTT_ControlPacketType dataType="uint" bitLength="4" stringRepresentation="CONNECT">1</MQTT_ControlPacketType>
+        </packetType>
+        <MQTT_ControlPacket_CONNECT>
+          <reserved dataType="uint" bitLength="4">0</reserved>
+          <remainingLength dataType="uint" bitLength="8">29</remainingLength>
+          <protocolName>
+            <MQTT_String>
+              <stringLength dataType="uint" bitLength="16">4</stringLength>
+              <value dataType="string" bitLength="32" encoding="UTF-8">MQTT</value>
+            </MQTT_String>
+          </protocolName>
+          <protocolVersion dataType="uint" bitLength="8">5</protocolVersion>
+          <userNameFlagSet dataType="bit" bitLength="1">true</userNameFlagSet>
+          <passwordFlagSet dataType="bit" bitLength="1">true</passwordFlagSet>
+          <willRetainFlagSet dataType="bit" bitLength="1">false</willRetainFlagSet>
+          <willQosLevel dataType="uint" bitLength="2">0</willQosLevel>
+          <willFlagSet dataType="bit" bitLength="1">false</willFlagSet>
+          <cleanStartFlagSet dataType="bit" bitLength="1">true</cleanStartFlagSet>
+          <reserved dataType="bit" bitLength="1">false</reserved>
+          <keepAlive dataType="uint" bitLength="16">5</keepAlive>
+          <value dataType="uint" bitLength="8">0</value>
+          <properties isList="true">
+          </properties>
+          <clientId>
+            <MQTT_String>
+              <stringLength dataType="uint" bitLength="16">6</stringLength>
+              <value dataType="string" bitLength="48" encoding="UTF-8">lwmqtt</value>
+            </MQTT_String>
+          </clientId>
+          <username>
+            <MQTT_String>
+              <stringLength dataType="uint" bitLength="16">3</stringLength>
+              <value dataType="string" bitLength="24" encoding="UTF-8">try</value>
+            </MQTT_String>
+          </username>
+          <password>
+            <MQTT_String>
+              <stringLength dataType="uint" bitLength="16">3</stringLength>
+              <value dataType="string" bitLength="24" encoding="UTF-8">try</value>
+            </MQTT_String>
+          </password>
+        </MQTT_ControlPacket_CONNECT>
+      </MQTT_ControlPacket>
+    </xml>
+  </testcase>
+
+</test:testsuite>
\ No newline at end of file
diff --git a/protocols/pom.xml b/protocols/pom.xml
index 268f669..ea21e96 100644
--- a/protocols/pom.xml
+++ b/protocols/pom.xml
@@ -44,6 +44,7 @@
     <module>genericcan</module>
     <module>knxnetip</module>
     <module>modbus</module>
+    <module>mqtt</module>
     <module>opcua</module>
     <module>plc4x</module>
     <module>profinet</module>
diff --git a/sandbox/mqtt/mqtt-c/pom.xml b/sandbox/mqtt/mqtt-c/pom.xml
new file mode 100644
index 0000000..4e8fc83
--- /dev/null
+++ b/sandbox/mqtt/mqtt-c/pom.xml
@@ -0,0 +1,319 @@
+<?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
+
+      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.
+  -->
+<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.sandbox</groupId>
+    <artifactId>test-plc4x-mqtt</artifactId>
+    <version>0.10.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>test-plc4x-mqtt-c</artifactId>
+  <packaging>pom</packaging>
+  <name>Sandbox: Test MQTT Driver: C</name>
+
+  <properties>
+    <unity.version>2.5.2</unity.version>
+    <option.with-proxies>OFF</option.with-proxies>
+  </properties>
+
+  <!--
+    Notes:
+    - It turns out that the default version of CMake the cmake-maven-plugin uses is too
+    old to detect the recent boost version. So we need to manually download a newer version
+    and tell the plugin to use that instead.
+    - As downloading and building boost takes quite some time, we only do this, if no
+    target/lib/boost is found.
+  -->
+
+  <profiles>
+    <!-- Profile for linux -->
+    <profile>
+      <id>os-unix</id>
+      <activation>
+        <os>
+          <family>unix</family>
+        </os>
+      </activation>
+      <!-- Make the cmake executable executable -->
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>exec-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>make-cmake-executable</id>
+                <phase>process-sources</phase>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <configuration>
+                  <basedir>${cmake.root}</basedir>
+                  <executable>chmod</executable>
+                  <arguments>
+                    <argument>+x</argument>
+                    <argument>cmake</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <!-- Profile for mac -->
+    <profile>
+      <id>os-mac</id>
+      <activation>
+        <os>
+          <family>mac</family>
+        </os>
+      </activation>
+      <!-- Make the cmake executable executable -->
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>exec-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>make-cmake-executable</id>
+                <phase>process-sources</phase>
+                <goals>
+                  <goal>exec</goal>
+                </goals>
+                <configuration>
+                  <basedir>${cmake.root}</basedir>
+                  <executable>chmod</executable>
+                  <arguments>
+                    <argument>+x</argument>
+                    <argument>cmake</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>com.googlecode.maven-download-plugin</groupId>
+        <artifactId>download-maven-plugin</artifactId>
+        <executions>
+          <!-- First download the cmake binaries -->
+          <execution>
+            <id>get-cmake</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>wget</goal>
+            </goals>
+            <configuration>
+              <url>${cmake.url}</url>
+              <unpack>true</unpack>
+              <outputDirectory>${project.build.directory}</outputDirectory>
+            </configuration>
+          </execution>
+          <!--
+            Get additional stuff we need for the build.
+          -->
+          <execution>
+            <id>get-unity</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>wget</goal>
+            </goals>
+            <configuration>
+              <url>https://github.com/ThrowTheSwitch/Unity/archive/v${unity.version}.zip</url>
+              <unpack>true</unpack>
+              <outputDirectory>${project.build.directory}/dependency</outputDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!--
+        Generate the driver code.
+      -->
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-driver-mqtt</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>mqtt</protocolName>
+              <languageName>c</languageName>
+              <outputFlavor>read-write</outputFlavor>
+              <outputDir>${project.basedir}/generated-sources</outputDir>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!--
+        Do the actual build.
+      -->
+      <plugin>
+        <groupId>com.googlecode.cmake-maven-project</groupId>
+        <artifactId>cmake-maven-plugin</artifactId>
+        <executions>
+          <!-- TODO: Commented out for now as when running in jenkins for code analysis, the second run would overwrite the results of the first -->
+          <!-- Generate the configuration for the main compilation -->
+          <!--execution>
+            <id>cmake-generate-compile</id>
+            <phase>compile</phase>
+            <goals>
+              <goal>generate</goal>
+            </goals>
+          </execution>
+          <!- Compile the main code ->
+          <execution>
+            <id>cmake-execute-compile</id>
+            <phase>compile</phase>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+          </execution-->
+          <!-- Generate the configuration for the test compilation -->
+          <!--execution>
+            <id>cmake-generate-test-compile</id>
+            <phase>test-compile</phase>
+            <goals>
+              <goal>generate</goal>
+            </goals>
+            <configuration>
+              <options>
+                <option>-DUNITY_VERSION:STRING=${unity.version}</option>
+                <option>-DBUILD_PHASE=test-compile</option>
+              </options>
+            </configuration>
+          </execution-->
+          <!-- Compile the test code -->
+          <!--execution>
+            <id>cmake-execute-test-compile</id>
+            <phase>test-compile</phase>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+          </execution-->
+        </executions>
+        <configuration>
+          <!--
+            We need to use a newer version of cmake, so disable downloading
+            and tell the plugin where to find that version.
+          -->
+          <downloadBinaries>false</downloadBinaries>
+          <cmakeDir>${cmake.root}</cmakeDir>
+          <!--
+            Actually the path to the CMakeList.txt file which then again
+            tells to tool where to find the sources.
+          -->
+          <sourcePath>${project.basedir}</sourcePath>
+          <!--
+            Path to where the build configuration is generated
+            (This directory is then used in the compile step to actually perform the build)
+          -->
+          <targetPath>${project.build.directory}/build</targetPath>
+          <!--
+            Name of the generator the compile step will be executing.
+          -->
+          <generator>${cmake.generator}</generator>
+          <!-- The directory where the "generate" step generated the build configuration -->
+          <projectDirectory>${project.build.directory}/build</projectDirectory>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>run-tests</id>
+            <phase>test</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <basedir>${project.build.directory}/build</basedir>
+              <executable>${cmake.root}/ctest</executable>
+              <arguments>
+                <argument>--extra-verbose</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- For this module deploying maven artifacts doesn't make any sense -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+    <!--
+      Developers working in plc4c will probably use an IDE like CLion to edit just this
+      Part of the project. These IDEs generate some work-directories we need to exclude.
+    -->
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.rat</groupId>
+          <artifactId>apache-rat-plugin</artifactId>
+          <configuration>
+            <excludes combine.children="append">
+              <exclude>cmake-*/**</exclude>
+            </excludes>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <!-- This dependency is just to ensure thrift is built first -->
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-code-generation-language-c</artifactId>
+      <version>0.10.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-mqtt</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/sandbox/mqtt/mqtt-cs/pom.xml b/sandbox/mqtt/mqtt-cs/pom.xml
new file mode 100644
index 0000000..b5cdb3d
--- /dev/null
+++ b/sandbox/mqtt/mqtt-cs/pom.xml
@@ -0,0 +1,138 @@
+<?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
+
+      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.
+  -->
+<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.sandbox</groupId>
+    <artifactId>test-plc4x-mqtt</artifactId>
+    <version>0.10.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>test-plc4x-mqtt-cs</artifactId>
+  <packaging>pom</packaging>
+  <name>Sandbox: Test MQTT Driver: C#</name>
+
+  <!-- Disabled for now as C# support is currently not installed in Apache SonarQube -->
+  <!--properties>
+    <sonar.language>c#</sonar.language>
+  </properties-->
+
+  <build>
+    <plugins>
+      <!-- Copy the test-resources in here -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>unpack-protocol-test-suites</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.apache.plc4x</groupId>
+                  <artifactId>plc4x-protocols-mqtt</artifactId>
+                  <classifier>tests</classifier>
+                  <type>test-jar</type>
+                  <outputDirectory>${project.basedir}/drivers/mqtt/resources</outputDirectory>
+                  <includes>**/*.xml</includes>
+                  <excludes>META-INF/**,org/**</excludes>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!--
+        Generate the driver code.
+      -->
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-driver-mqtt</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>mqtt</protocolName>
+              <languageName>C#</languageName>
+              <outputFlavor>read-write</outputFlavor>
+              <outputDir>${project.basedir}/drivers/mqtt/src</outputDir>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- Build the project -->
+      <!--plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>dotnet-build</id>
+            <phase>compile</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <executable>dotnet</executable>
+              <workingDirectory>${project.basedir}</workingDirectory>
+              <arguments>
+                <argument>build</argument>
+                <argument>plc4net.sln</argument>
+                <argument>- -configuration=Debug</argument>
+                <argument>- -output=${project.build.directory}/build</argument>
+                <argument>-p:Version=${project.version}</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin-->
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-code-generation-language-cs</artifactId>
+      <version>0.10.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-mqtt</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/sandbox/mqtt/mqtt-go/pom.xml b/sandbox/mqtt/mqtt-go/pom.xml
new file mode 100644
index 0000000..5f7caf1
--- /dev/null
+++ b/sandbox/mqtt/mqtt-go/pom.xml
@@ -0,0 +1,352 @@
+<?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
+
+      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.
+  -->
+<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.sandbox</groupId>
+    <artifactId>test-plc4x-mqtt</artifactId>
+    <version>0.10.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>test-plc4x-mqtt-go</artifactId>
+  <!--packaging>mvn-golang</packaging-->
+  <packaging>pom</packaging>
+  <name>Sandbox: Test MQTT Driver: Go</name>
+
+  <properties>
+    <!-- Tell Sonar where to find the sources -->
+    <sonar.sources>cmd,examples,internal,pkg</sonar.sources>
+  </properties>
+
+  <build>
+    <sourceDirectory>cmd</sourceDirectory>
+    <plugins>
+      <!--
+        Copy the test-resources in here
+      -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>unpack-protocol-test-suites</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.apache.plc4x</groupId>
+                  <artifactId>plc4x-protocols-mqtt</artifactId>
+                  <classifier>tests</classifier>
+                  <type>test-jar</type>
+                  <outputDirectory>${project.basedir}/assets/testing</outputDirectory>
+                  <includes>**/*.xml</includes>
+                  <excludes>META-INF/**</excludes>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!--
+        Generate the driver code.
+      -->
+      <plugin>
+        <groupId>org.apache.plc4x.plugins</groupId>
+        <artifactId>plc4x-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-driver-mqtt</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate-driver</goal>
+            </goals>
+            <configuration>
+              <protocolName>mqtt</protocolName>
+              <languageName>go</languageName>
+              <outputFlavor>read-write</outputFlavor>
+              <outputDir>${project.basedir}/internal</outputDir>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!--plugin>
+        <groupId>com.igormaznitsa</groupId>
+        <artifactId>mvn-golang-wrapper</artifactId>
+        <version>2.3.9</version>
+        <extensions>true</extensions>
+        <executions>
+
+          <!- - Downloads the dependencies of the project - ->
+          <execution>
+            <id>default-get</id>
+            <phase>initialize</phase>
+            <goals>
+              <goal>get</goal>
+            </goals>
+          </execution>
+
+          <!- - Make sure the "stringer" extension as well als the "licenser" is downloaded - ->
+          <execution>
+            <id>get-tools</id>
+            <phase>initialize</phase>
+            <goals>
+              <goal>get</goal>
+            </goals>
+            <configuration>
+              <packages>
+                <package>golang.org/x/tools/cmd/stringer</package>
+                <package>github.com/elastic/go-licenser</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <!- - Run the go code-generation - ->
+          <execution>
+            <id>default-generate</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>generate</goal>
+            </goals>
+            <configuration>
+              <packages>
+                <!- - We want to format every package here so we don't get dirty commits - ->
+                <package>./...</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <!- - Add the apache license header to stuff generated by the stringer - ->
+          <!- -
+            NOTE: Don't try merging the following 4 executions ...
+                  It doesn't work by merging the "packages" sections
+          - ->
+          <execution>
+            <id>add-license</id>
+            <phase>process-sources</phase>
+            <goals>
+              <goal>custom</goal>
+            </goals>
+            <configuration>
+              <exec>go-licenser</exec>
+              <customCommand>-licensor</customCommand>
+              <buildFlags>
+                <flag>Apache Software Foundation (ASF)</flag>
+              </buildFlags>
+              <packages>
+                <package>internal/plc4go/mqtt/fieldtype_string.go</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <!- - Processes code that uses old APIs and rewrites them use newer ones - ->
+          <execution>
+            <id>default-fix</id>
+            <phase>process-sources</phase>
+            <goals>
+              <goal>fix</goal>
+            </goals>
+          </execution>
+
+          <!- - Format the codebase correctly (this mainly has an effect on generated code) - ->
+          <execution>
+            <id>default-fmt</id>
+            <phase>process-sources</phase>
+            <goals>
+              <goal>fmt</goal>
+            </goals>
+            <configuration>
+              <packages>
+                <!- - We want to format every package here so we don't get dirty commits - ->
+                <package>./...</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <!- - Get all dependencies for test cases - ->
+          <execution>
+            <id>get-test-dependencies</id>
+            <phase>generate-test-sources</phase>
+            <goals>
+              <goal>get</goal>
+            </goals>
+            <configuration>
+              <buildFlags>
+                <flag>-t</flag>
+              </buildFlags>
+              <packages>
+                <package>./...</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <!- - Make sure the xunit generator as well as gotestsum is installed - ->
+          <execution>
+            <id>test-get</id>
+            <phase>process-test-resources</phase>
+            <goals>
+              <goal>get</goal>
+            </goals>
+            <configuration>
+              <packages>
+                <package>github.com/tebeka/go2xunit</package>
+                <package>gotest.tools/gotestsum</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <!- - Check all tests with producing report file in Golang format - ->
+          <execution>
+            <id>default-test</id>
+            <phase>test</phase>
+            <!- - TODO: Which goal?!? - ->
+            <configuration>
+              <buildFlags>
+                <flag>-v</flag>
+              </buildFlags>
+              <outLogFile>test-out-verbose.log</outLogFile>
+              <ignoreErrorExitCode>true</ignoreErrorExitCode>
+              <packages>
+                <package>./...</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <execution>
+            <id>readable-test</id>
+            <!- - TODO: Possibly move to test or prepare-package - ->
+            <phase>test</phase>
+            <goals>
+              <goal>custom</goal>
+            </goals>
+            <configuration>
+              <exec>gotestsum</exec>
+              <customCommand>-f</customCommand>
+              <buildFlags>
+                <flag>short</flag>
+              </buildFlags>
+              <packages>
+                <package>./...</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <!- - Convert generated test report into xunit format and save as file - ->
+          <execution>
+            <id>makeXUnitReport</id>
+            <phase>test</phase>
+            <goals>
+              <goal>custom</goal>
+            </goals>
+            <configuration>
+              <skip>${skipTests}</skip>
+              <exec>go2xunit</exec>
+              <customCommand>-fail</customCommand>
+              <buildFlags>
+                <flag>-input</flag>
+                <flag>${project.build.directory}${file.separator}reports${file.separator}test-out-verbose.log</flag>
+                <flag>-output</flag>
+              </buildFlags>
+              <echo>
+                <info>XUnit report saved as ${xunit.report}</info>
+              </echo>
+              <packages>
+                <package>target${file.separator}surefire-reports${file.separator}xuint.xml</package>
+              </packages>
+            </configuration>
+          </execution>
+
+          <execution>
+            <id>run-go-vet</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>vet</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <packages>
+            <package>github.com/apache/plc4x/plc4go/cmd/main</package>
+          </packages>
+          <sources>${project.basedir}</sources>
+          <verbose>true</verbose>
+        </configuration>
+      </plugin-->
+
+      <!--
+        Create surefire folder for report
+      -->
+      <!--plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <version>3.0.0</version>
+        <executions>
+          <execution>
+            <id>generate-sources</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <target>
+                <mkdir dir="target${file.separator}surefire-reports" />
+              </target>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin-->
+
+      <!-- For this module deploying maven artifacts doesn't make any sense -->
+      <!--plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin-->
+    </plugins>
+  </build>
+
+  <!-- This dependency is just to ensure thrift is built first -->
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-code-generation-language-go</artifactId>
+      <version>0.10.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-mqtt</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+      <!-- Scope is 'provided' as this way it's not shipped with the driver -->
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/sandbox/mqtt/mqtt-java/pom.xml b/sandbox/mqtt/mqtt-java/pom.xml
new file mode 100644
index 0000000..ddf884e
--- /dev/null
+++ b/sandbox/mqtt/mqtt-java/pom.xml
@@ -0,0 +1,116 @@
+<?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
+
+      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.
+  -->
+<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.sandbox</groupId>
+    <artifactId>test-plc4x-mqtt</artifactId>
+    <version>0.10.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>test-plc4x-mqtt-java</artifactId>
+  <name>Sandbox: Test MQTT Driver: Java</name>
+
+  <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>mqtt</protocolName>
+              <languageName>java</languageName>
+              <outputFlavor>read-write</outputFlavor>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-api</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-spi</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-transport-tcp</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-transport-raw-socket</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-utils-test-utils</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4x-code-generation-language-java</artifactId>
+      <version>0.10.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-mqtt</artifactId>
+      <version>0.10.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-mqtt</artifactId>
+      <version>0.10.0-SNAPSHOT</version>
+      <classifier>tests</classifier>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/sandbox/mqtt/mqtt-java/src/test/java/org/apache/plc4x/java/mqtt/readwrite/MqttParserSerializerTest.java b/sandbox/mqtt/mqtt-java/src/test/java/org/apache/plc4x/java/mqtt/readwrite/MqttParserSerializerTest.java
new file mode 100644
index 0000000..0d72840
--- /dev/null
+++ b/sandbox/mqtt/mqtt-java/src/test/java/org/apache/plc4x/java/mqtt/readwrite/MqttParserSerializerTest.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
+ *
+ *   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.mqtt.readwrite;
+
+import org.apache.plc4x.test.parserserializer.ParserSerializerTestsuiteRunner;
+
+public class MqttParserSerializerTest extends ParserSerializerTestsuiteRunner {
+
+    public MqttParserSerializerTest() {
+        super("/protocols/mqtt/ParserSerializerTestsuite.xml");
+    }
+
+}
diff --git a/sandbox/mqtt/pom.xml b/sandbox/mqtt/pom.xml
new file mode 100644
index 0000000..7cc4053
--- /dev/null
+++ b/sandbox/mqtt/pom.xml
@@ -0,0 +1,41 @@
+<?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
+
+      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.
+  -->
+<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.sandbox</groupId>
+    <artifactId>plc4x-sandbox</artifactId>
+    <version>0.10.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>test-plc4x-mqtt</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Sandbox: Test MQTT Driver</name>
+
+  <modules>
+    <module>mqtt-c</module>
+    <module>mqtt-cs</module>
+    <module>mqtt-go</module>
+    <module>mqtt-java</module>
+  </modules>
+
+</project>
diff --git a/sandbox/pom.xml b/sandbox/pom.xml
index 80ffbca..22abe69 100644
--- a/sandbox/pom.xml
+++ b/sandbox/pom.xml
@@ -37,6 +37,7 @@
   <modules>
     <module>code-gen</module>
     <module>discovery</module>
+    <module>mqtt</module>
     <module>plc-simulator</module>
 
     <module>test-java-bacnetip-driver</module>