Ryan Malloy 1464fcabe6 Refactor: extract KLineTransport and IbusHandler from IbusEsp32
Split the monolithic IbusEsp32 class into composable layers:
- KLineTransport: UART, GPIO ISR, ring buffers, idle detection
- IbusHandler: BMW I/K-Bus FSM, source filtering, packet callback
- IbusEsp32: thin facade preserving the original API

Library renamed from IbusEsp32 to AutoWire. Existing sniffer
sketch (main.cpp) requires zero changes. All 3 ESP32 environments
build cleanly (esp32dev, esp32-c3, esp32-s3).
2026-02-13 05:41:39 -07:00

62 lines
1.4 KiB
C++

// Ring buffer for async I/K-Bus message handling
// Based on muki01/I-K_Bus RingBuffer (MIT license)
#include "RingBuffer.h"
#include <cstring>
RingBuffer::RingBuffer(int size) : _size(size), _head(0), _tail(0) {
_buf = (byte*)malloc(size);
if (_buf) {
memset(_buf, 0, size);
} else {
// Allocation failed — disable all operations
log_e("RingBuffer: malloc(%d) failed", size);
_size = 0;
}
}
RingBuffer::~RingBuffer() {
if (_buf) free(_buf);
}
int RingBuffer::available() {
return (_size + _head - _tail) % _size;
}
int RingBuffer::capacity() {
return (_size > 0) ? _size - 1 : 0;
}
int RingBuffer::read() {
if (_head == _tail) return -1;
byte c = _buf[_tail];
_tail = (_tail + 1) % _size;
return c;
}
byte RingBuffer::write(int c) {
if (_size == 0) return -1;
if ((_head + 1) % _size == _tail) return -1; // full
_buf[_head] = c;
_head = (_head + 1) % _size;
return 0;
}
void RingBuffer::remove(int n) {
if (_head == _tail) return;
int avail = available();
if (n > avail) n = avail; // clamp to prevent state corruption
if (n <= 0) return;
_tail = (_tail + n) % _size;
}
int RingBuffer::peek() {
if (_head == _tail) return -1;
return _buf[_tail];
}
int RingBuffer::peek(int n) {
if (n < 0 || n >= available()) return -1;
return _buf[(_tail + n) % _size];
}