diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d53e38..89d6893 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ set(AVCLAN_TARGET avr-attiny3216 CACHE STRING "Hardware target (port) to build") # , no register access). The selected target's port sources and flags # are contributed by its subdirectory. add_library(avclan STATIC - src/avclan/avclan_frame.c + src/avclan/frame.cc src/avclan/cdchanger.cc src/avclan/bus.cc ) diff --git a/src/avclan/avclan_defs.h b/src/avclan/avclan_defs.h index 8bacaac..b279258 100644 --- a/src/avclan/avclan_defs.h +++ b/src/avclan/avclan_defs.h @@ -11,11 +11,6 @@ #include -#define MAXMSGLEN 32 - -#define DEVICE_ADDR 0x360 // CD Changer address -#define HU_ADDR 0x190 // Head-unit address - typedef enum : uint8_t { dev_LAN = 0x00, dev_COMM_CTRL = 0x01, @@ -109,23 +104,6 @@ typedef enum : uint8_t { Report_TOC = 0xf9, } actions; -typedef struct print_struct { - bool print : 1; // print at all - bool binary : 1; // when also printing, format as binary instead of text - bool verbose : 1; // include extra context in error reports -} log_t; - -typedef struct AVCLAN_frame_struct { - uint8_t reaction; - uint8_t owning_device; - bool is_unicast; - uint16_t controller_addr; // formerly "master" - uint16_t peripheral_addr; // formerly "slave" - uint8_t control; - uint8_t length; - uint8_t data[MAXMSGLEN]; -} AVCLAN_frame_t; - // A single bus symbol. bit_zero/bit_one carry data (and double as parity // values); bit_start marks a frame start bit. typedef enum avclan_bit : uint8_t { diff --git a/src/avclan/avclan_frame.c b/src/avclan/avclan_frame.c deleted file mode 100644 index c3830b3..0000000 --- a/src/avclan/avclan_frame.c +++ /dev/null @@ -1,114 +0,0 @@ -// copyright (C) 2006 Marcin Slonicki -// copyright (C) 2007 Louis Frigon -// Copyright (C) 2015 Allen Hill -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include - -#include "avclan_frame.h" -#include "avclan_phy.h" // bus symbol I/O + transaction guard (target-provided) -#include "com232.h" // error logging - -void AVCLAN_printframe(const AVCLAN_frame_t *frame, bool binary) { - if (binary) { - uint8_t buffer[8]; - buffer[0] = 0x10; // Data Link Escape, signaling binary data forthcoming - buffer[1] = frame->is_unicast; - - // Send addresses in big-endian order - buffer[2] = (uint8_t)(frame->controller_addr >> 8); - buffer[3] = (uint8_t)frame->controller_addr; - buffer[4] = (uint8_t)(frame->peripheral_addr >> 8); - buffer[5] = (uint8_t)frame->peripheral_addr; - - buffer[6] = frame->control; - buffer[7] = frame->length; - RS232_sendbytes((uint8_t *)&buffer, 8); - RS232_sendbytes(frame->data, frame->length); - - buffer[0] = 0x17; // End of transmission block - buffer[1] = 0x0D; // \r - buffer[2] = 0x0A; // \n - RS232_sendbytes((uint8_t *)&buffer, 3); - } else { - RS232_PrintHex4(frame->is_unicast); - - RS232_Print(" 0x"); - RS232_PrintHex12(frame->controller_addr); - RS232_Print(" 0x"); - RS232_PrintHex12(frame->peripheral_addr); - - RS232_Print(" 0x"); - RS232_PrintHex4(frame->control); - - RS232_Print(" 0x"); - RS232_PrintHex4(frame->length); - - for (uint8_t i = 0; i < frame->length; i++) { - RS232_Print(" 0x"); - RS232_PrintHex8(frame->data[i]); - } - RS232_Print("\n"); - } -} - -uint8_t AVCLAN_parseframe(const uint8_t *bytes, uint8_t len, - AVCLAN_frame_t *frame) { - struct errtype { - enum : uint8_t { - TOO_SHORT = 0x01, - MISMATCH_LENGTH, - LENGTH_TOO_BIG, - } errno; - uint8_t val; - } err = {0}; - - if (len < sizeof(AVCLAN_frame_t)) { - err.errno = TOO_SHORT; - goto handle_err; - } - const uint8_t *last = bytes + len; - - frame->is_unicast = *bytes++; - frame->controller_addr = bytes[0] | ((uint16_t)bytes[1] << 8); - bytes += 2; - frame->peripheral_addr = bytes[0] | ((uint16_t)bytes[1] << 8); - bytes += 2; - frame->control = *bytes++; - frame->length = *bytes++; - - if (frame->length > MAXMSGLEN) { - err.errno = LENGTH_TOO_BIG; - err.val = frame->length; - goto handle_err; - } - - if ((bytes + frame->length) <= last) { - memcpy(frame->data, bytes, frame->length); - } else { - err.errno = MISMATCH_LENGTH; - goto handle_err; - } - - if (false) { - handle_err:; - RS232_Print("ERR(parse): "); - switch (err.errno) { - case TOO_SHORT: - RS232_Print("not enough bytes too fill AVCLAN frame"); - break; - case MISMATCH_LENGTH: - RS232_Print("frame->length is longer than remaining data"); - break; - case LENGTH_TOO_BIG: - RS232_Print("frame->length exceeds MAXMSGLEN: 0x"); - RS232_PrintHex8(err.val); - break; - default: break; - } - RS232_Print("\n"); - } - - return err.errno; -} diff --git a/src/avclan/avclan_frame.h b/src/avclan/avclan_frame.h deleted file mode 100644 index f62ce77..0000000 --- a/src/avclan/avclan_frame.h +++ /dev/null @@ -1,48 +0,0 @@ -// copyright (C) 2006 Marcin Slonicki -// copyright (C) 2007 Louis Frigon -// Copyright (C) 2015 Allen Hill -// SPDX-License-Identifier: GPL-3.0-or-later - -/* - AVC LAN Frame Format - │ Bits │ Description - ──────────────────────────────────────── - | 1 │ Start bit - | 1 │ Direct/broadcast - | 12 │ Controller address - | 1 │ Parity - | 12 │ Peripheral address - | 1 │ Parity - | 1 │ *Acknowledge* (read below) - | 4 │ Control - | 1 │ Parity - | 1 │ *Acknowledge* - | 8 │ Message length (n) - | 1 │ Parity - | 1 │ *Acknowledge* - ──────── - | 8 │ Data - | 1 │ Parity - | 1 │ *Acknowledge* - *repeat `n` times* - - No acknowledge bits are sent for broadcast frames. -*/ - -#pragma once - -#include - -#include "avclan_defs.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void AVCLAN_printframe(const AVCLAN_frame_t *frame, bool binary); -uint8_t AVCLAN_parseframe(const uint8_t *bytes, uint8_t len, - AVCLAN_frame_t *frame); - -#ifdef __cplusplus -} -#endif diff --git a/src/avclan/avclandrv.h b/src/avclan/avclandrv.h index 53ac0b1..08402e0 100644 --- a/src/avclan/avclandrv.h +++ b/src/avclan/avclandrv.h @@ -9,7 +9,6 @@ #pragma once #include "avclan_defs.h" -#include "avclan_frame.h" #include "avclan_phy.h" #include "mediacontrol.h" #include "statustimer.h" diff --git a/src/avclan/bus.cc b/src/avclan/bus.cc index 4c6d24e..2f93442 100644 --- a/src/avclan/bus.cc +++ b/src/avclan/bus.cc @@ -32,9 +32,9 @@ #include "bus.hpp" #include "avclan.hpp" #include "avclan_defs.h" -#include "avclan_frame.h" #include "avclan_phy.h" // bridge until phy has been ported #include "com232.h" +#include "frame.hpp" namespace { constexpr int ADDR_WIDTH = 12; @@ -45,8 +45,7 @@ void Bus::init() { AVCLAN_busInit(); }; void Bus::mute(bool mute) { AVCLAN_muteDevice(mute); }; bool Bus::is_muted() const { return AVCLAN_ismuted(); }; -auto Bus::read(uint16_t address, AVCLAN_frame_t *in, log_t print) - -> Error::Read { +auto Bus::read(uint16_t address, Frame *in, Frame::Print print) -> Error::Read { struct errtype { Error::Read errno; union { @@ -113,7 +112,7 @@ auto Bus::read(uint16_t address, AVCLAN_frame_t *in, log_t print) goto handle_err; } - if (in->length == 0 || in->length > MAXMSGLEN) { + if (in->length == 0 || in->length > Frame::MAXLENGTH) { err.errno = BAD_LENGTH_RANGE; err.val = in->length; goto handle_err; @@ -169,13 +168,13 @@ auto Bus::read(uint16_t address, AVCLAN_frame_t *in, log_t print) if (print.print && (err.errno < STARTBIT_TOO_SHORT)) { if (err.errno > BAD_DATA_PARITY) in->length = 0; - AVCLAN_printframe(in, print.binary); + in->print(print); } return err.errno; } -auto Bus::send(const AVCLAN_frame_t *out, log_t print) -> Error::Send { +auto Bus::send(const Frame *out, Frame::Print print) -> Error::Send { struct errtype { // Error enum is ordered such that a lower numeric value corresponds to // more success @@ -267,7 +266,7 @@ auto Bus::send(const AVCLAN_frame_t *out, log_t print) -> Error::Send { } if (print.print) - AVCLAN_printframe(out, print.binary); + out->print(print); return err.errno; } diff --git a/src/avclan/bus.hpp b/src/avclan/bus.hpp index c2b724c..2b4c86d 100644 --- a/src/avclan/bus.hpp +++ b/src/avclan/bus.hpp @@ -52,6 +52,7 @@ #include "avclan.hpp" #include "avclan_defs.h" #include "avclan_phy.h" // bridge until phy has been ported +#include "frame.hpp" namespace avclan { class Bus { @@ -63,8 +64,8 @@ public: void mute(bool mute); bool is_muted() const; - Error::Read read(uint16_t address, AVCLAN_frame_t *in, log_t print); - Error::Send send(const AVCLAN_frame_t *out, log_t print); + Error::Read read(uint16_t address, Frame *in, Frame::Print print); + Error::Send send(const Frame *out, Frame::Print print); static Handle get(); }; diff --git a/src/avclan/cdchanger.cc b/src/avclan/cdchanger.cc index 67d0a67..ac2f7e2 100644 --- a/src/avclan/cdchanger.cc +++ b/src/avclan/cdchanger.cc @@ -8,6 +8,7 @@ #include "avclan_defs.h" #include "cdchanger.hpp" +#include "frame.hpp" #include "mediacontrol.h" #include "statustimer.h" @@ -53,7 +54,7 @@ void CDChanger::init() { statustimer_init(this, &incrementTime_callback, &isPlaying_callback); } -void CDChanger::handle(const AVCLAN_frame_t *in, AVCLAN_frame_t *out) { +void CDChanger::handle(const Frame *in, Frame *out) { const uint8_t *data = &in->data[1]; const auto from = static_cast(*data++); /* const auto to = */ data++; @@ -244,7 +245,7 @@ void CDChanger::handle(const AVCLAN_frame_t *in, AVCLAN_frame_t *out) { } } -void CDChanger::react(AVCLAN_frame_t *out, detail::Error::Send err) { +void CDChanger::react(Frame *out, detail::Error::Send err) { auto resp = static_cast(out->reaction); out->reaction = r_Nothing; switch (resp) { @@ -302,7 +303,7 @@ void CDChanger::react(AVCLAN_frame_t *out, detail::Error::Send err) { } } -void CDChanger::enable(AVCLAN_frame_t *out) { +void CDChanger::enable(Frame *out) { if (!isPlaying()) { if (mins > TWODIGIT_MAX) mins = 0; @@ -318,7 +319,7 @@ void CDChanger::enable(AVCLAN_frame_t *out) { bool CDChanger::pending() { return statustimer_tickPending(); } void CDChanger::resolvepending() { statustimer_clearTick(); } -void CDChanger::emit(AVCLAN_frame_t *out) { +void CDChanger::emit(Frame *out) { generateStatus(out, true, dev_STATUS); out->reaction = r_StateReport; } @@ -377,7 +378,7 @@ void CDChanger::incrementTime() { } // Used for changed status messages -void CDChanger::generateStatus(AVCLAN_frame_t *status, bool is_unicast, +void CDChanger::generateStatus(Frame *status, bool is_unicast, devices to) const { status->is_unicast = is_unicast; if (!is_unicast) diff --git a/src/avclan/cdchanger.hpp b/src/avclan/cdchanger.hpp index 659f419..828125e 100644 --- a/src/avclan/cdchanger.hpp +++ b/src/avclan/cdchanger.hpp @@ -9,6 +9,7 @@ #include "avclan.hpp" #include "avclan_defs.h" +#include "frame.hpp" namespace avclan { @@ -59,13 +60,13 @@ public: static constexpr uint8_t id = dev_CD_CHANGER; void init(); - void handle(const AVCLAN_frame_t *in, AVCLAN_frame_t *out); - void react(AVCLAN_frame_t *out, detail::Error::Send err); - void enable(AVCLAN_frame_t *out); - void disable(AVCLAN_frame_t *out); + void handle(const Frame *in, Frame *out); + void react(Frame *out, detail::Error::Send err); + void enable(Frame *out); + void disable(Frame *out); static bool pending(); static void resolvepending(); - void emit(AVCLAN_frame_t *out); + void emit(Frame *out); void incrementTime(); bool isPlaying() const; @@ -74,8 +75,7 @@ private: void stopPlaying(); void serialize(uint8_t *dst) const; void setTime(uint8_t mins, uint8_t secs); - void generateStatus(AVCLAN_frame_t *status, bool is_unicast, - devices to) const; + void generateStatus(Frame *status, bool is_unicast, devices to) const; void normalizeState(); bool playing = false; diff --git a/src/avclan/device.hpp b/src/avclan/device.hpp index 17c7609..9315a7d 100644 --- a/src/avclan/device.hpp +++ b/src/avclan/device.hpp @@ -4,22 +4,22 @@ #pragma once #include "avclan.hpp" -#include "avclan_defs.h" +#include "frame.hpp" #include #include namespace avclan { template -concept Device = requires { std::integral_constant{}; } && - requires(T dev, const AVCLAN_frame_t *in, AVCLAN_frame_t *out, - detail::Error::Send err) { - dev.init(); - dev.handle(in, out); - dev.enable(out); - dev.react(out, err); - { dev.pending() } -> std::convertible_to; - dev.resolvepending(); - dev.emit(out); - }; +concept Device = requires { + std::integral_constant{}; +} && requires(T dev, const Frame *in, Frame *out, detail::Error::Send err) { + dev.init(); + dev.handle(in, out); + dev.enable(out); + dev.react(out, err); + { dev.pending() } -> std::convertible_to; + dev.resolvepending(); + dev.emit(out); +}; } // namespace avclan diff --git a/src/avclan/frame.cc b/src/avclan/frame.cc new file mode 100644 index 0000000..bca3a4b --- /dev/null +++ b/src/avclan/frame.cc @@ -0,0 +1,118 @@ +// copyright (C) 2006 Marcin Slonicki +// copyright (C) 2007 Louis Frigon +// Copyright (C) 2015 Allen Hill +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include + +#include "com232.h" // error logging +#include "frame.hpp" + +namespace { +using Error = avclan::Frame::Error; +using enum Error::Parse; +} // namespace + +namespace avclan { +void Frame::print(Frame::Print print) const { + if (print.binary) { + uint8_t buffer[8]; + uint8_t *bptr = buffer; + *bptr++ = 0x10; // Data Link Escape, signaling binary data forthcoming + *bptr++ = static_cast(is_unicast); + + // Send addresses in big-endian order + *bptr++ = static_cast(controller_addr >> 8); + *bptr++ = static_cast(controller_addr); + *bptr++ = static_cast(peripheral_addr >> 8); + *bptr++ = static_cast(peripheral_addr); + + *bptr++ = control; + *bptr++ = length; + RS232_sendbytes(buffer, 8); + RS232_sendbytes(data, length); + + bptr = buffer; + *bptr++ = 0x17; // End of transmission block + *bptr++ = 0x0D; // \r + *bptr++ = 0x0A; // \n + RS232_sendbytes(buffer, 3); + } else { + RS232_PrintHex4(static_cast(is_unicast)); + + RS232_Print(" 0x"); + RS232_PrintHex12(controller_addr); + RS232_Print(" 0x"); + RS232_PrintHex12(peripheral_addr); + + RS232_Print(" 0x"); + RS232_PrintHex4(control); + + RS232_Print(" 0x"); + RS232_PrintHex4(length); + + for (uint8_t i = 0; i < length; i++) { + RS232_Print(" 0x"); + RS232_PrintHex8(data[i]); + } + RS232_Print("\n"); + } +} + +Error::Parse Frame::parse(const uint8_t *bytes, uint8_t len) { + struct errtype { + Error::Parse errno; + uint8_t val; + } err = {}; + + const uint8_t *last = bytes + len; + + if (len < sizeof(avclan::Frame)) { + err.errno = TOO_SHORT; + goto handle_err; + } + + is_unicast = (*bytes++ != 0U); + controller_addr = bytes[0] | ((uint16_t)bytes[1] << 8); + bytes += 2; + peripheral_addr = bytes[0] | ((uint16_t)bytes[1] << 8); + bytes += 2; + control = *bytes++; + length = *bytes++; + + if (length > MAXLENGTH) { + err.errno = LENGTH_TOO_BIG; + err.val = length; + goto handle_err; + } + + if ((bytes + length) <= last) { + memcpy(data, bytes, length); + } else { + err.errno = MISMATCH_LENGTH; + goto handle_err; + } + + if (false) { // NOLINT(readability-simplify-boolean-expr) + handle_err:; + RS232_Print("ERR(parse): "); + switch (err.errno) { + case TOO_SHORT: + RS232_Print("not enough bytes too fill AVCLAN frame"); + break; + case MISMATCH_LENGTH: + RS232_Print("frame->length is longer than remaining data"); + break; + case LENGTH_TOO_BIG: + RS232_Print("frame->length exceeds MAXLENGTH: 0x"); + RS232_PrintHex8(err.val); + break; + default: break; + } + RS232_Print("\n"); + } + + return err.errno; +} +} // namespace avclan diff --git a/src/avclan/frame.hpp b/src/avclan/frame.hpp new file mode 100644 index 0000000..307bbdd --- /dev/null +++ b/src/avclan/frame.hpp @@ -0,0 +1,38 @@ +// copyright (C) 2006 Marcin Slonicki +// copyright (C) 2007 Louis Frigon +// Copyright (C) 2015 Allen Hill +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +namespace avclan { +struct Frame { + struct Print { + bool print : 1 = false; // print at all + bool binary : 1 = false; // if printing, format as binary instead of text + bool verbose : 1 = false; // include extra context in error reports + }; + struct Error { + enum class Parse : uint8_t { + TOO_SHORT = 0x01, + MISMATCH_LENGTH, + LENGTH_TOO_BIG, + }; + }; + static constexpr int MAXLENGTH = 32; + + Error::Parse parse(const uint8_t *bytes, uint8_t len); + void print(Print print) const; + + uint8_t reaction; + uint8_t owning_device; + bool is_unicast; + uint16_t controller_addr; // formerly "master" + uint16_t peripheral_addr; // formerly "slave" + uint8_t control = 0xF; + uint8_t length; + uint8_t data[MAXLENGTH]; +}; +} // namespace avclan diff --git a/src/avclan/peripheral.hpp b/src/avclan/peripheral.hpp index 86656ac..73ff1c3 100644 --- a/src/avclan/peripheral.hpp +++ b/src/avclan/peripheral.hpp @@ -7,6 +7,7 @@ #include "avclan_defs.h" #include "bus.hpp" #include "device.hpp" +#include "frame.hpp" #include #include @@ -24,16 +25,16 @@ public: uint16_t address() const { return address_; }; - Error::Read read(AVCLAN_frame_t *in, log_t print) { + Error::Read read(Frame *in, Frame::Print print) { return bus.read(address_, in, print); }; - Error::Send send(const AVCLAN_frame_t *out, log_t print) { + Error::Send send(const Frame *out, Frame::Print print) { return bus.send(out, print); }; #define PACK3(a, b, c) (((uint32_t)(a) << 16) | ((uint32_t)(b) << 8) | (c)) - void route(const AVCLAN_frame_t *in, AVCLAN_frame_t *out) { + void route(const Frame *in, Frame *out) { out->reaction = 0; if (AVCLAN_ismuted() || in->length < 3) @@ -119,7 +120,7 @@ public: } } - void react(AVCLAN_frame_t *out, Error::Send err) { + void react(Frame *out, Error::Send err) { if (((Devs::id == out->owning_device) || ...)) ((Devs::id == out->owning_device ? std::get(devices_).react(out, err), @@ -141,7 +142,7 @@ private: dev.resolvepending(); } template - void device_preroute(Dev dev, const AVCLAN_frame_t *in, AVCLAN_frame_t *out) { + void device_preroute(Dev dev, const Frame *in, Frame *out) { out->owning_device = Dev::id; dev.handle(in, out); } diff --git a/src/sniffer.cc b/src/sniffer.cc index b16088d..f0afaf7 100644 --- a/src/sniffer.cc +++ b/src/sniffer.cc @@ -11,6 +11,7 @@ #include "board.h" #include "cdchanger.hpp" #include "com232.h" +#include "frame.hpp" #include "peripheral.hpp" #include "queue.hpp" @@ -18,8 +19,10 @@ const char *const offon[] = {"OFF", "ON"}; constexpr uint8_t CACHE_SIZE = 32; +using namespace avclan; + namespace { -AVCLAN_frame_t frames[CACHE_SIZE]; +Frame frames[CACHE_SIZE]; constinit Queue cache(frames); constinit Queue incoming = cache; @@ -60,17 +63,13 @@ int main() { // Binary-mode REPL includes the full wire preamble (broadcast + 2*addr + // control + length), so size for the worst case. - uint8_t data_tmp[MAXMSGLEN + sizeof(AVCLAN_frame_t)]; + uint8_t data_tmp[Frame::MAXLENGTH + sizeof(Frame)]; uint8_t seqIdx = 0; // current index in data_tmp - // Temporary, direct access is questionable since cache has ownership - for (auto &frame : frames) { - frame.control = 0x0f; - } - - avclan::Bus phy; - avclan::Peripheral cd_changer(phy, 0x360); - using Error = decltype(cd_changer)::Error; + Bus phy; + Peripheral peripheral(phy, 0x360); + using Error = decltype(peripheral)::Error; + using Print = Frame::Print; Setup(); print_help(); @@ -78,9 +77,9 @@ int main() { while (true) { if (AVCLAN_busActive()) { if (auto msg = cache.pop()) { - auto err = cd_changer.read(msg.get(), (log_t){.print = printAllFrames, - .binary = printBinary, - .verbose = verbose}); + auto err = peripheral.read(msg.get(), Print{.print = printAllFrames, + .binary = printBinary, + .verbose = verbose}); if (err == Error::Read{0x00}) incoming.push(std::move(msg)); } else { @@ -90,7 +89,7 @@ int main() { if (const auto *in = incoming.peek()) { if (auto out = cache.pop()) { - cd_changer.route(in, out.get()); + peripheral.route(in, out.get()); incoming.pop(); if (out->reaction > 0) @@ -100,7 +99,7 @@ int main() { } } - cd_changer.poll_devices([&](auto dev) { + peripheral.poll_devices([&](auto dev) { if (auto status = cache.pop()) { dev.emit(status.get()); outgoing.push(std::move(status)); @@ -110,9 +109,9 @@ int main() { }); if (auto out = outgoing.pop()) { - auto err = cd_changer.send( - out.get(), (log_t){.print = printAllFrames, .binary = printBinary}); - cd_changer.react(out.get(), err); + auto err = peripheral.send( + out.get(), Print{.print = printAllFrames, .binary = printBinary}); + peripheral.react(out.get(), err); if (out->reaction > 0) outgoing.push(std::move(out)); } @@ -139,8 +138,8 @@ int main() { case 'E': // Beep if (auto out = cache.pop()) { out->is_unicast = true; - out->controller_addr = cd_changer.address(); - out->peripheral_addr = HU_ADDR; + out->controller_addr = peripheral.address(); + out->peripheral_addr = peripheral.controller(); { const uint8_t beep[] = {0x00, dev_CD_CHANGER, dev_BEEP_SPEAKERS, 0x60, 0x01}; @@ -154,15 +153,15 @@ int main() { case 'P': if (auto out = cache.pop()) { out->is_unicast = true; - out->controller_addr = cd_changer.address(); - out->peripheral_addr = HU_ADDR; + out->controller_addr = peripheral.address(); + out->peripheral_addr = peripheral.controller(); { const uint8_t play[] = {0x00, dev_COMM_CTRL, dev_COMM_v1, Ejection, dev_CD_CHANGER, 0x01}; out->length = sizeof(play); memcpy(out->data, play, sizeof(play)); } - out->reaction = avclan::CDChanger::reaction_t::r_Ejection; + out->reaction = CDChanger::reaction_t::r_Ejection; outgoing.push(std::move(out)); } break; @@ -224,7 +223,8 @@ int main() { if (readBinary) { if (data_tmp[seqIdx] == 0x17) { if (auto out = cache.pop()) { - if (!AVCLAN_parseframe(data_tmp, --seqIdx, out.get())) { + if (out->parse(data_tmp, --seqIdx) == + Frame::Error::Parse{0}) { out->reaction = 1; outgoing.push(std::move(out)); } @@ -236,8 +236,9 @@ int main() { } else { if (auto out = cache.pop()) { out->is_unicast = seqIsUnicast; - out->controller_addr = cd_changer.address(); - out->peripheral_addr = seqIsUnicast ? HU_ADDR : 0x1FF; + out->controller_addr = peripheral.address(); + out->peripheral_addr = + seqIsUnicast ? peripheral.controller() : 0x1FF; out->length = seqIdx; memcpy(out->data, data_tmp, seqIdx); out->reaction = 1;