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).
62 lines
1.4 KiB
C++
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];
|
|
}
|