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

63 lines
1.5 KiB
C++

#pragma once
// BMW I/K-Bus protocol handler
// Extracted from IbusEsp32 — FSM, source filtering, packet callback.
// Reads from a KLineTransport's RX ring buffer, delegates TX to transport.
#include <Arduino.h>
#include <functional>
#include "KLineTransport.h"
#ifndef IBUS_MIN_LENGTH
#define IBUS_MIN_LENGTH 0x03
#endif
#ifndef IBUS_MAX_LENGTH
#define IBUS_MAX_LENGTH 0x24
#endif
#ifndef IBUS_MAX_MSG
#define IBUS_MAX_MSG 40
#endif
class IbusHandler {
public:
using PacketCallback = std::function<void(const uint8_t* packet, uint8_t length)>;
explicit IbusHandler(KLineTransport& transport);
// Run the receive FSM — call from loop() after transport.drainUart()
void process();
// Queue a BMW I/K-Bus message for TX (checksum appended by transport)
void write(const uint8_t* message, uint8_t size);
// Register callback for received packets
void onPacket(PacketCallback callback);
// Source address filtering
void setFilterEnabled(bool enabled);
void setFilterAddress(uint8_t addr);
void setFilterAddresses(const uint8_t* addrs, uint8_t count);
private:
enum FsmState {
FIND_SOURCE,
FIND_LENGTH,
FIND_MESSAGE,
GOOD_CHECKSUM,
BAD_CHECKSUM,
};
KLineTransport& _transport;
FsmState _state;
uint8_t _source;
uint8_t _length;
uint8_t _msgBuf[IBUS_MAX_MSG];
unsigned long _findMsgEnteredMs;
PacketCallback _callback;
bool _filterEnabled;
uint8_t _filterAddrs[16];
uint8_t _filterCount;
};