diff --git a/.gitignore b/.gitignore
index 56d98aa..9b993eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,6 @@
# re-include specifically what is desired from images folder
!/images/contact.jpg
!/ccsds-frames-cfdp
+
+# include xtce-decoding folder
+!/xtce-decoding
diff --git a/README.md b/README.md
index 2f833eb..cb3a9ac 100644
--- a/README.md
+++ b/README.md
@@ -49,3 +49,9 @@ When a stream of CCSDS telemetry is available from a TCP client only, this clien
### ccsds-frames-cfdp
This is the same as the ccsds-frames example from yamcs but with the addition of the CFDP service. The CFDP shares the same virtual channel with the regular TCs but has lower priority.
+
+### xtce-decoding
+Shows how to use Yamcs as a general-purpose library for decoding packets based on an XTCE XML definition.
+It decodes a single packet initialized in the code, and prints the result to the terminal.
+To run: $ mvn exec:java
+
diff --git a/ccsds-frames-cfdp/.classpath b/ccsds-frames-cfdp/.classpath
index c6bb293..a896564 100644
--- a/ccsds-frames-cfdp/.classpath
+++ b/ccsds-frames-cfdp/.classpath
@@ -13,7 +13,7 @@
-
+
@@ -36,5 +36,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ccsds-frames-cfdp/.settings/org.eclipse.jdt.apt.core.prefs b/ccsds-frames-cfdp/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000..d4313d4
--- /dev/null
+++ b/ccsds-frames-cfdp/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/ccsds-frames-cfdp/.settings/org.eclipse.jdt.core.prefs b/ccsds-frames-cfdp/.settings/org.eclipse.jdt.core.prefs
index eeac0e7..1b6e1ef 100644
--- a/ccsds-frames-cfdp/.settings/org.eclipse.jdt.core.prefs
+++ b/ccsds-frames-cfdp/.settings/org.eclipse.jdt.core.prefs
@@ -1,8 +1,9 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
-org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
-org.eclipse.jdt.core.compiler.release=enabled
-org.eclipse.jdt.core.compiler.source=17
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/xtce-decoding/.gitignore b/xtce-decoding/.gitignore
new file mode 100644
index 0000000..0a2101f
--- /dev/null
+++ b/xtce-decoding/.gitignore
@@ -0,0 +1 @@
+/cache/
diff --git a/xtce-decoding/mdb/xtce_v12_UT.xml b/xtce-decoding/mdb/xtce_v12_UT.xml
new file mode 100644
index 0000000..ea97654
--- /dev/null
+++ b/xtce-decoding/mdb/xtce_v12_UT.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+ 8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xtce-decoding/pom.xml b/xtce-decoding/pom.xml
new file mode 100644
index 0000000..5b42b70
--- /dev/null
+++ b/xtce-decoding/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ org.yamcs.snippets
+ xtce-decoding
+ jar
+ 1.0.0
+
+ Yamcs :: Examples :: XTCE Decoding
+
+ Shows how to use Yamcs as a general-purpose library for decoding packets based on an XTCE XML definition.
+
+
+
+ 5.12.4-SNAPSHOT
+
+
+
+
+ org.yamcs
+ yamcs-core
+ ${yamcsVersion}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.8
+ 1.8
+
+
+
+ org.yamcs
+ yamcs-maven-plugin
+ 1.2.9
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+ org.yamcs.snippets.XtceDecodingSnippet
+
+
+
+
+
diff --git a/xtce-decoding/src/main/java/org/yamcs/snippets/XtceDecodingSnippet.java b/xtce-decoding/src/main/java/org/yamcs/snippets/XtceDecodingSnippet.java
new file mode 100644
index 0000000..7bfcc11
--- /dev/null
+++ b/xtce-decoding/src/main/java/org/yamcs/snippets/XtceDecodingSnippet.java
@@ -0,0 +1,56 @@
+package org.yamcs.snippets;
+
+import java.util.logging.LogManager;
+
+import org.yamcs.mdb.ContainerProcessingResult;
+import org.yamcs.mdb.Mdb;
+import org.yamcs.mdb.MdbFactory;
+import org.yamcs.mdb.XtceTmExtractor;
+import org.yamcs.parameter.ParameterValue;
+import org.yamcs.parameter.Value;
+import org.yamcs.utils.TimeEncoding;
+
+/**
+ * Shows how to use Yamcs as a general-purpose library for decoding packets based on an XTCE XML definition.
+ */
+public class XtceDecodingSnippet {
+
+ public static void main(String... args) {
+ // Make Yamcs aware of leap seconds
+ TimeEncoding.setUp();
+
+ // Silence log messages from Yamcs libraries
+ LogManager.getLogManager().reset();
+
+ // The name here must match with an entry in mdb.yaml which by
+ // default is scanned from the classpath.
+ Mdb mdb = MdbFactory.createInstanceByConfig("example", false);
+ XtceTmExtractor extractor = new XtceTmExtractor(mdb);
+
+ // Tell the extractor to do a full scan. For efficiency reasons
+ // you may also instruct it to scan only the parameters or containers
+ // of your choice.
+ extractor.provideAll();
+
+ // Generate a fake packet that matches our example XTCE definition.
+ byte[] p1 = new byte[] {
+ (byte) 0xA7, // SyncByte1
+ (byte) 0xF3, // SyncByte2
+ (byte) ((5 << 5) | 31), // SubsystemID
+ 0x00, 0x00, 0x00, 0x06, // NumberOfDataBytesFollowing
+ 0x00, 0x10, 0x02, 0x00, 0x30, 0x04
+ }; // 4 Samples
+
+ long t = TimeEncoding.getWallclockTime();
+ ContainerProcessingResult result = extractor.processPacket(p1, t, t, 0);
+
+ System.out.printf("%-30s %-15s %-15s\n", "Parameter", "Engineering", "Raw");
+ System.out.printf("%-30s %-15s %-15s\n", "---------", "-----------", "---");
+ for (ParameterValue value : result.getParameterResult()) {
+ String parameterName = value.getParameter().getName();
+ Value engValue = value.getEngValue();
+ Value rawValue = value.getRawValue();
+ System.out.printf("%-30s %-15s %-15s\n", parameterName, engValue, rawValue);
+ }
+ }
+}
diff --git a/xtce-decoding/src/main/resources/mdb.yaml b/xtce-decoding/src/main/resources/mdb.yaml
new file mode 100644
index 0000000..d673b47
--- /dev/null
+++ b/xtce-decoding/src/main/resources/mdb.yaml
@@ -0,0 +1,6 @@
+example:
+ - type: org.yamcs.mdb.XtceLoader
+ args:
+ # This path reference is resolved from the file system.
+ # Relative paths start from your cwd
+ file: "mdb/xtce_v12_UT.xml"
diff --git a/xtce-decoding/target/classes/mdb.yaml b/xtce-decoding/target/classes/mdb.yaml
new file mode 100644
index 0000000..d673b47
--- /dev/null
+++ b/xtce-decoding/target/classes/mdb.yaml
@@ -0,0 +1,6 @@
+example:
+ - type: org.yamcs.mdb.XtceLoader
+ args:
+ # This path reference is resolved from the file system.
+ # Relative paths start from your cwd
+ file: "mdb/xtce_v12_UT.xml"
diff --git a/xtce-decoding/target/classes/org/yamcs/snippets/XtceDecodingSnippet.class b/xtce-decoding/target/classes/org/yamcs/snippets/XtceDecodingSnippet.class
new file mode 100644
index 0000000..3a6c316
Binary files /dev/null and b/xtce-decoding/target/classes/org/yamcs/snippets/XtceDecodingSnippet.class differ
diff --git a/xtce-decoding/target/maven-archiver/pom.properties b/xtce-decoding/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..6177063
--- /dev/null
+++ b/xtce-decoding/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Mon Dec 15 13:54:48 CET 2025
+groupId=org.yamcs.snippets
+artifactId=xtce-decoding
+version=1.0.0
diff --git a/xtce-decoding/target/xtce-decoding-1.0.0.jar b/xtce-decoding/target/xtce-decoding-1.0.0.jar
new file mode 100644
index 0000000..0f9dce9
Binary files /dev/null and b/xtce-decoding/target/xtce-decoding-1.0.0.jar differ