diff --git a/README.md b/README.md
index 9906ec6..fad61b7 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ Añade la dependencia a tu `pom.xml`:
com.flamingo
llp-protocol
- 3.0.0
+ 3.0.1
```
@@ -324,7 +324,7 @@ Las nuevas capas de protocolo se implementan como módulos de Maven independient
com.flamingo
llp-protocol
- 3.0.0
+ 3.0.1
```
@@ -454,17 +454,17 @@ if (deepest instanceof FinalNode final) {
## 🔄 Migración desde v2.x
-La versión 3.0 introduce un nuevo modelo de tramas en capas y una API pública rediseñada. La API de la v2 ha sido eliminada.
-
-| v2.x | v3.0 |
-| --- | --- |
-| `LLP.newParser()` | `LLP.incrementalParser().build()` |
-| `parser.processByte(b)` | `parser.feed(b)` + `parser.pollFrames()` |
-| `parser.addListener(...)` | Maneja los resultados desde `pollFrames()` / `pollErrors()` |
-| `LLP.buildData(type, payload)` | `LLP.frameBuilder().build()` + `.build(payload)` |
-| `LLPFrame.getType()` | Eliminado — el tipo de mensaje es ahora un asunto de la capa |
-| `LLPFrame.getId()` | Eliminado — el ID de transacción es ahora un asunto de la capa |
-| `LLPMessageType` | Eliminado — define los tipos de mensajes en tu capa |
+La versión 3 introduce un nuevo modelo de tramas en capas y una API pública rediseñada. La API de la v2 ha sido eliminada.
+
+| v2.x | v3.x |
+| --- |-----------------------------------------------------------------------|
+| `LLP.newParser()` | `LLP.incrementalParser().build()` |
+| `parser.processByte(b)` | `parser.feed(b)` + `parser.pollFrames()` |
+| `parser.addListener(...)` | Maneja los resultados desde `pollFrames()` / `pollErrors()` |
+| `LLP.buildData(type, payload)` | `LLP.frameBuilder().build()` + `.build(payload)` |
+| `LLPFrame.getType()` | Eliminado — el tipo de mensaje es ahora un asunto de la capa |
+| `LLPFrame.getId()` | Eliminado — el ID de transacción es ahora un asunto de la capa |
+| `LLPMessageType` | Eliminado — define los tipos de mensajes en tu capa |
| Formato de trama única | Modelo de cebolla en capas (layered onion model) con capas opcionales |
El formato de la trama cambió significativamente en la v3 para soportar el modelo de capas. Las tramas v2 y v3 **no son compatibles a nivel de red (wire-compatible)**.
@@ -528,8 +528,8 @@ Creado por **EnzoLeonel**
---
-**Versión:** 3.0.0
+**Versión:** 3.0.1
-**Última actualización:** 2026-05-08
+**Última actualización:** 2026-05-13
**Objetivo Java:** 21+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index feb003e..580a9b5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.flamingo
llp-core
- 3.0.0
+ 3.0.1
jar
LLP Core
diff --git a/src/main/java/com/flamingo/comm/llp/core/LLPTransportDeframer.java b/src/main/java/com/flamingo/comm/llp/core/LLPTransportDeframer.java
index abaa50f..239e68c 100644
--- a/src/main/java/com/flamingo/comm/llp/core/LLPTransportDeframer.java
+++ b/src/main/java/com/flamingo/comm/llp/core/LLPTransportDeframer.java
@@ -108,6 +108,7 @@ public LLPRawFrame processByte(byte b) {
if (b == MAGIC_1) {
state = State.WAIT_MAGIC2;
}
+ lastByteTime = System.currentTimeMillis();
return null;
}
}
diff --git a/src/test/java/com/flamingo/comm/llp/core/LLPTransportDeframerTest.java b/src/test/java/com/flamingo/comm/llp/core/LLPTransportDeframerTest.java
index e66b4e9..59af26d 100644
--- a/src/test/java/com/flamingo/comm/llp/core/LLPTransportDeframerTest.java
+++ b/src/test/java/com/flamingo/comm/llp/core/LLPTransportDeframerTest.java
@@ -143,6 +143,35 @@ void testTimeoutResetsParser() throws InterruptedException {
assertTrue(deframer.getStatistics().getTimeouts() > 0);
}
+ @Test
+ void testTimeoutThenResyncDoesNotCascadeTimeout() throws InterruptedException {
+ byte[] payload = new byte[]{0x00};
+ byte[] fullFrame = buildFrame(payload);
+
+ deframer.processByte(fullFrame[0]);
+ deframer.processByte(fullFrame[1]);
+
+ Thread.sleep(2100);
+
+ deframer.processByte((byte) 0xAA);
+
+ LLPRawFrame result = null;
+ for (int i = 1; i < fullFrame.length; i++) {
+ LLPRawFrame f = deframer.processByte(fullFrame[i]);
+ if (f != null) result = f;
+ }
+
+ assertNotNull(result,
+ "Frame must complete after timeout+resync");
+ ByteBuffer buf = result.payload();
+ byte[] extracted = new byte[buf.remaining()];
+ buf.get(extracted);
+ assertArrayEquals(payload, extracted);
+
+ assertEquals(1, deframer.getStatistics().getTimeouts(),
+ "Exactly 1 timeout — no cascading");
+ }
+
@Test
void testPayloadExceedsMaximum() {
byte[] payload = new byte[1025]; // max is 1024