@@ -363,8 +363,11 @@ namespace tinylink {
363363 // Update: Main RX State Machine
364364 // -------------------------------------------------------------------------
365365 void update () {
366- if (!_hw->isOpen () || _hasNew) return ;
367- // ---- Handshake and timeout logic: unchanged ----
366+ if (!_hw->isOpen () || _hasNew) {
367+ return ;
368+ }
369+
370+ // --- Handshake and timeout logic ---
368371 if (_state == TinyState::CONNECTING) {
369372 if (_handshakeTimer == 0 ) {
370373 _sendStatus ();
@@ -394,32 +397,21 @@ namespace tinylink {
394397 _stats.timeouts ++;
395398 }
396399
400+ // --- RX Parse state machine ---
397401 while (_hw->available () > 0 ) {
398402 int incoming = _hw->read ();
399-
400- if (incoming < 0 ) {
401- break ;
402- }
403+ if (incoming < 0 ) break ;
403404
404405 uint8_t c = (uint8_t )incoming;
405406 _lastByte = _hw->millis ();
406- // --- Robust RX resync: Discard until delimiter ---
407- if (_inResync) {
408- if (c == 0x00 ) {
409- _inResync = false ;
410- _rawIdx = 0 ; // FULL state reset!
411- break ;
412- }
413- continue ; // Discard all other bytes.
414- }
415- // Frame delimiter detected (COBS frame boundary)
407+
416408 if (c == 0x00 ) {
417- if (_rawIdx >= 5 ) {
409+ // Frame boundary detected
410+ if (_state == TinyState::IN_FRAME && _rawIdx > 0 ) {
411+ // Try to decode the just-completed frame
418412 size_t dLen = cobs_decode (_rawBuf, _rawIdx, _pBuf);
419- _rawIdx = 0 ;
420- if (_state == TinyState::IN_FRAME) {
421- _state = TinyState::WAIT_FOR_SYNC;
422- }
413+ _rawIdx = 0 ; // Always reset after delimiter
414+ _state = TinyState::WAIT_FOR_SYNC;
423415
424416 if (dLen >= 3 ) {
425417 uint8_t msgType = _pBuf[0 ];
@@ -450,40 +442,33 @@ namespace tinylink {
450442 }
451443 else {
452444 _stats.crcErrs ++;
453- _inResync = true ;
454445 }
455446 }
456447 else {
457448 _stats.crcErrs ++;
458- _inResync = true ;
459449 }
460450 }
451+ // else: frame was too short/bad; ignore
461452 }
462- else {
463- _rawIdx = 0 ;
464- if (_state == TinyState::IN_FRAME) {
465- _state = TinyState::WAIT_FOR_SYNC;
466- }
467- }
453+ // Always ready to start a new frame after delimiter
454+ _state = TinyState::IN_FRAME;
455+ _rawIdx = 0 ;
468456 continue ;
469457 }
470458
471- // Accumulate next frame byte
472- if (_rawIdx < sizeof (_rawBuf)) {
473- _rawBuf[_rawIdx++] = c;
474-
475- if (_state == TinyState::WAIT_FOR_SYNC) {
476- _state = TinyState::IN_FRAME;
459+ // Only accumulate frame bytes if we're in IN_FRAME state
460+ if (_state == TinyState::IN_FRAME) {
461+ if (_rawIdx < sizeof (_rawBuf)) {
462+ _rawBuf[_rawIdx++] = c;
477463 }
478- }
479- else {
480- _overflowErrs++;
481- _rawIdx = 0 ;
482- if (_state == TinyState::IN_FRAME) {
464+ else {
465+ // Buffer overflow: count error and revert to sync wait
466+ _stats.crcErrs ++;
483467 _state = TinyState::WAIT_FOR_SYNC;
468+ _rawIdx = 0 ;
484469 }
485- _inResync = true ;
486470 }
471+ // If not IN_FRAME, ignore data until delimiter resets us
487472 }
488473 }
489474
0 commit comments