From 554fca058278d8421fb9559a01ef8a08e7e966b1 Mon Sep 17 00:00:00 2001 From: Allen Hill Date: Mon, 6 Jul 2026 15:50:09 -0700 Subject: [PATCH] Shift Device/Action enums to avclan.h --- CMakeLists.txt | 4 +- src/avclan/avclan.h | 100 +++++++++++++++++++++++++++++- src/avclan/avclan_defs.h | 105 ------------------------------- src/avclan/cdchanger.cc | 126 ++++++++++++++++++++++---------------- src/avclan/cdchanger.hpp | 6 +- src/avclan/device.hpp | 49 ++++++++++----- src/avclan/frame.hpp | 4 +- src/avclan/peripheral.hpp | 60 ++++++++++-------- src/sniffer.cc | 17 +++-- 9 files changed, 261 insertions(+), 210 deletions(-) delete mode 100644 src/avclan/avclan_defs.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 89d6893..1223195 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,9 @@ cmake_minimum_required(VERSION 3.24) project(avclan-mockingboard VERSION 1.1 LANGUAGES C CXX) set(CMAKE_C_STANDARD 23) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) add_compile_options( diff --git a/src/avclan/avclan.h b/src/avclan/avclan.h index da7fc97..51d9271 100644 --- a/src/avclan/avclan.h +++ b/src/avclan/avclan.h @@ -7,12 +7,105 @@ #ifdef __cplusplus #define AVCLAN_ENUM_CLASS class -namespace avclan::detail { -struct Error { + + #include + #include + +namespace avclan { + + #if defined(__cpp_lib_to_underlying) && __cpp_lib_to_underlying >= 202102L +using std::to_underlying; + #else +template + requires std::is_enum_v +constexpr std::underlying_type_t to_underlying(Enum e) noexcept { + return static_cast>(e); +} + #endif + #else #define AVCLAN_ENUM_CLASS #endif +enum AVCLAN_ENUM_CLASS Action : uint8_t { + // LAN related + List_Functions_Req = 0x00, + List_Functions_Resp = 0x10, + Restart_Lan = 0x01, + // Lan_Startup_Complete = 0x58, + Lancheck_End_Req = 0x08, + Lancheck_End_Resp = 0x18, + Lancheck_Scan_Req = 0x0a, + Lancheck_Scan_Resp = 0x1a, + Lancheck_Req = 0x0c, + Lancheck_Resp = 0x1c, + // Lancheck_UNK_Req = 0x0d, + // Lancheck_UNK_Resp = 0x1d, + Ping_Req = 0x20, + Ping_Resp = 0x30, + + // Device switching + Enable_Function_Req = 0x42, + Enable_Function_Resp = 0x52, + Disable_Function_Req = 0x43, + Disable_Function_Resp = 0x53, + + Current_Function = 0x45, + General_Query = 0x46, + + // Events + Insertion = 0x50, + Ejection = 0x51, + + // Physical interface + Backlight_Adjust = 0x59, + Beep = 0x60, + Eject = 0x80, + Disc_Up = 0x90, + Disc_Down = 0x91, + Track_Seek_Up = 0x94, + Track_Seek_Down = 0x95, + Track_Fast_Forward = 0x98, + Track_Rewind = 0x99, + Pwrvol_Knob_Righthand_Turn = 0x9c, + Pwrvol_Knob_Lefthand_Turn = 0x9d, + CD_Enable_Repeat = 0xa0, + CD_Disable_Repeat = 0xa1, + CD_Enable_Disk_Repeat = 0xa3, + CD_Disable_Disk_Repeat = 0xa4, + CD_Enable_Scan = 0xa6, + CD_Disable_Scan = 0xa7, + CD_Enable_Disk_Scan = 0xa9, + CD_Disable_Disk_Scan = 0xaa, + CD_Enable_Random = 0xb0, + CD_Disable_Random = 0xb1, + CD_Enable_Disk_Random = 0xb3, + CD_Disable_Disk_Random = 0xb4, + + // Requests and Response pairs + Initial_Report_Request = 0xe0, + Initial_Report_Response = 0xf0, + + Playback_Request = 0xe2, + Playback_Report = 0xf2, + + Loading_Request2 = 0xe4, + Loading_Response2 = 0xf4, + + Request_Track_Name = 0xed, + Report_Track_Name = 0xfd, + + // Reports + Status_Report = 0xf1, // Typically unprompted, sent to Device::STATUS + Loading_Status_Report = 0xf3, // Typically unprompted, sent to Device::STATUS + Report_TOC = 0xf9, +}; + +#ifdef __cplusplus +namespace detail { +struct Error { +#endif + // Error enums are ordered such that a lower numeric value corresponds to // more progress/success before an error occured, with 0 being no errors enum AVCLAN_ENUM_CLASS Read : uint8_t { @@ -49,7 +142,8 @@ enum AVCLAN_ENUM_CLASS Bit : uint8_t { }; #ifdef __cplusplus -} // namespace avclan::detail +} // namespace detail +} // namespace avclan #endif #undef AVCLAN_ENUM_CLASS diff --git a/src/avclan/avclan_defs.h b/src/avclan/avclan_defs.h deleted file mode 100644 index 9c59194..0000000 --- a/src/avclan/avclan_defs.h +++ /dev/null @@ -1,105 +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 - -// Shared cross-cutting AVC-LAN definitions used by two or more layers -// (phy / frame / protocol / cdchanger). This is a leaf header: it must not -// include any other project header. - -#pragma once - -#include - -typedef enum : uint8_t { - dev_LAN = 0x00, - dev_COMM_CTRL = 0x01, - dev_COMM_v1 = 0x11, - dev_COMM_v2 = 0x12, - dev_SW = 0x21, - dev_SW_NAME = 0x23, - dev_SW_CONVERTING = 0x24, - dev_CMD_SW = 0x25, - dev_STATUS = 0x31, - dev_BEEP_HU = 0x28, - dev_BEEP_SPEAKERS = 0x29, - dev_TUNER = 0x60, - dev_TAPE_DECK = 0x61, - dev_CD = 0x62, - dev_CD_CHANGER = 0x63, - dev_AUDIO_AMP = 0x74, -} devices; - -typedef enum : uint8_t { - // LAN related - List_Functions_Req = 0x00, - List_Functions_Resp = 0x10, - Restart_Lan = 0x01, - // Lan_Startup_Complete = 0x58, - Lancheck_End_Req = 0x08, - Lancheck_End_Resp = 0x18, - Lancheck_Scan_Req = 0x0a, - Lancheck_Scan_Resp = 0x1a, - Lancheck_Req = 0x0c, - Lancheck_Resp = 0x1c, - // Lancheck_UNK_Req = 0x0d, - // Lancheck_UNK_Resp = 0x1d, - Ping_Req = 0x20, - Ping_Resp = 0x30, - - // Device switching - Enable_Function_Req = 0x42, - Enable_Function_Resp = 0x52, - Disable_Function_Req = 0x43, - Disable_Function_Resp = 0x53, - - Current_Function = 0x45, - General_Query = 0x46, - - // Events - Insertion = 0x50, - Ejection = 0x51, - - // Physical interface - Backlight_Adjust = 0x59, - Beep = 0x60, - Eject = 0x80, - Disc_Up = 0x90, - Disc_Down = 0x91, - Track_Seek_Up = 0x94, - Track_Seek_Down = 0x95, - Track_Fast_Forward = 0x98, - Track_Rewind = 0x99, - Pwrvol_Knob_Righthand_Turn = 0x9c, - Pwrvol_Knob_Lefthand_Turn = 0x9d, - CD_Enable_Repeat = 0xa0, - CD_Disable_Repeat = 0xa1, - CD_Enable_Disk_Repeat = 0xa3, - CD_Disable_Disk_Repeat = 0xa4, - CD_Enable_Scan = 0xa6, - CD_Disable_Scan = 0xa7, - CD_Enable_Disk_Scan = 0xa9, - CD_Disable_Disk_Scan = 0xaa, - CD_Enable_Random = 0xb0, - CD_Disable_Random = 0xb1, - CD_Enable_Disk_Random = 0xb3, - CD_Disable_Disk_Random = 0xb4, - - // Requests and Response pairs - Initial_Report_Request = 0xe0, - Initial_Report_Response = 0xf0, - - Playback_Request = 0xe2, - Playback_Report = 0xf2, - - Loading_Request2 = 0xe4, - Loading_Response2 = 0xf4, - - Request_Track_Name = 0xed, - Report_Track_Name = 0xfd, - - // Reports - Status_Report = 0xf1, // Typically unprompted, sent to dev_STATUS - Loading_Status_Report = 0xf3, // Typically unprompted, sent to dev_STATUS - Report_TOC = 0xf9, -} actions; diff --git a/src/avclan/cdchanger.cc b/src/avclan/cdchanger.cc index e015bb8..79b0a28 100644 --- a/src/avclan/cdchanger.cc +++ b/src/avclan/cdchanger.cc @@ -6,24 +6,27 @@ #include #include -#include "avclan_defs.h" +#include "avclan.h" #include "cdchanger.hpp" +#include "device.hpp" #include "frame.hpp" #include "mediacontrol.h" #include "statustimer.h" namespace { +using namespace avclan; -constexpr uint8_t cdloading_resp[] = {dev_CD_CHANGER, - dev_STATUS, - Loading_Status_Report, - 0x00, - 0x01, - 0x00, - 0x01, - 0x00, - 0x01, - 0x02}; +constexpr uint8_t cdloading_resp[] = { + to_underlying(Device::CD_CHANGER), + to_underlying(Device::STATUS), + to_underlying(Action::Loading_Status_Report), + 0x00, + 0x01, + 0x00, + 0x01, + 0x00, + 0x01, + 0x02}; constexpr int WIRE_SIZE = 8; // cd state report size in bytes constexpr int TIME_SKIP = 15; // seconds @@ -56,20 +59,23 @@ void CDChanger::init() { void CDChanger::handle(const Frame *in, Frame *out) { const uint8_t *data = &in->data[1]; - const auto from = static_cast(*data++); + const auto from = static_cast(*data++); /* const auto to = */ data++; - const auto action = *data++; + const auto action = static_cast(*data++); - static const uint8_t function_change_resp[] = {0x00, dev_CD_CHANGER, from, - 0xFF, 0x01}; + static const uint8_t function_change_resp[] = { + 0x00, to_underlying(Device::CD_CHANGER), to_underlying(from), 0xFF, 0x01}; + using enum Action; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wswitch-enum" // Unicast to CD changer: bytes are (0x00, from, to, action, [extra...]). switch (action) { case Enable_Function_Req: out->is_unicast = true; out->length = sizeof(function_change_resp); memcpy(out->data, function_change_resp, sizeof(function_change_resp)); - out->data[3] = Enable_Function_Resp; + out->data[3] = to_underlying(Enable_Function_Resp); state = 0; flags2 = 0x80; out->reaction = r_StatusReport; @@ -80,7 +86,7 @@ void CDChanger::handle(const Frame *in, Frame *out) { stopPlaying(); out->length = sizeof(function_change_resp); memcpy(out->data, function_change_resp, sizeof(function_change_resp)); - out->data[3] = Disable_Function_Resp; + out->data[3] = to_underlying(Disable_Function_Resp); state = 0; flags2 = 0x80; out->is_unicast = true; @@ -90,8 +96,9 @@ void CDChanger::handle(const Frame *in, Frame *out) { case Eject: { // "Eject" label is multiply wrong; proper meaning unclear: // - First observed on initial multiple presses of "CD" button, - // triggering (after {0x00, dev_CD_CHANGER, dev_COMM_v1, Insertion, - // 0x01} response) proper activation of mockingboard/cd-changer. + // triggering (after {0x00, Device::CD_CHANGER, Device::COMM_v1, + // Insertion, 0x01} response) proper activation of + // mockingboard/cd-changer. // - Subsequently observed when pressing (technically // releasing?) the fast-forward button and rewind if (static_cast(state & SEEKING)) { // FF/RW button released @@ -99,8 +106,9 @@ void CDChanger::handle(const Frame *in, Frame *out) { } else { out->is_unicast = true; { - const uint8_t msg[] = {0x00, dev_CD_CHANGER, dev_CMD_SW, Insertion, - 0x01}; + const uint8_t msg[] = {0x00, to_underlying(Device::CD_CHANGER), + to_underlying(Device::CMD_SW), + to_underlying(Insertion), 0x01}; out->length = sizeof(msg); memcpy(out->data, msg, sizeof(msg)); } @@ -112,8 +120,15 @@ void CDChanger::handle(const Frame *in, Frame *out) { out->is_unicast = true; // No knowledge/understanding of field meaning/interpretation const uint8_t cdinitreport_resp[] = { - 0x00, dev_CD_CHANGER, from, Initial_Report_Response, 0x01, 0x31, - 0x10, 0x01, 0x01}; + 0x00, + to_underlying(Device::CD_CHANGER), + to_underlying(from), + to_underlying(Initial_Report_Response), + 0x01, + 0x31, + 0x10, + 0x01, + 0x01}; out->length = sizeof(cdinitreport_resp); memcpy(out->data, cdinitreport_resp, sizeof(cdinitreport_resp)); out->reaction = r_SendOnly; @@ -121,9 +136,9 @@ void CDChanger::handle(const Frame *in, Frame *out) { } case Playback_Request: out->data[0] = 0x00; - out->data[1] = dev_CD_CHANGER; - out->data[2] = from; - out->data[3] = Playback_Report; + out->data[1] = to_underlying(Device::CD_CHANGER); + out->data[2] = to_underlying(from); + out->data[3] = to_underlying(Playback_Report); out->length = WIRE_SIZE + 4; serialize(&out->data[4]); out->is_unicast = true; @@ -133,8 +148,8 @@ void CDChanger::handle(const Frame *in, Frame *out) { out->data[0] = 0x00; out->length = sizeof(cdloading_resp) + 1; memcpy(&out->data[1], cdloading_resp, sizeof(cdloading_resp)); - out->data[2] = from; - out->data[3] = Loading_Response2; + out->data[2] = to_underlying(from); + out->data[3] = to_underlying(Loading_Response2); out->is_unicast = true; out->reaction = r_SendOnly; break; @@ -147,7 +162,7 @@ void CDChanger::handle(const Frame *in, Frame *out) { mins = 0xff; secs = 0x7f; flags2 = 0xc0; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); AVCLAN_mediaFunction(MEDIA_SKIP_FORWARD); out->reaction = r_TrackChange; break; @@ -163,7 +178,7 @@ void CDChanger::handle(const Frame *in, Frame *out) { mins = 0xff; secs = 0x7f; flags2 = 0xc0; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); AVCLAN_mediaFunction(MEDIA_SKIP_BACKWARD); out->reaction = r_TrackChange; break; @@ -174,7 +189,7 @@ void CDChanger::handle(const Frame *in, Frame *out) { secs -= 60; ++mins; } - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); AVCLAN_mediaFunction(MEDIA_SKIP_FORWARD); statustimer_reset(); // Skipped to a whole/round sec; ensure next tick // is ~1 sec from now @@ -194,7 +209,7 @@ void CDChanger::handle(const Frame *in, Frame *out) { } } else secs -= TIME_SKIP; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); AVCLAN_mediaFunction(MEDIA_SKIP_BACKWARD); statustimer_reset(); // Skipped to a whole/round sec; ensure next tick // is ~1 sec from now @@ -203,46 +218,47 @@ void CDChanger::handle(const Frame *in, Frame *out) { } case CD_Enable_Random: flags |= RANDOM; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); out->reaction = r_StatusReport; break; case CD_Disable_Random: flags &= ~RANDOM; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); out->reaction = r_StatusReport; break; case CD_Enable_Repeat: flags |= REPEAT; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); out->reaction = r_StatusReport; break; case CD_Disable_Repeat: flags &= ~REPEAT; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); out->reaction = r_StatusReport; break; case CD_Enable_Disk_Random: flags |= DISK_RANDOM; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); out->reaction = r_StatusReport; break; case CD_Disable_Disk_Random: flags &= ~DISK_RANDOM; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); out->reaction = r_StatusReport; break; case CD_Enable_Disk_Repeat: flags |= DISK_REPEAT; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); out->reaction = r_StatusReport; break; case CD_Disable_Disk_Repeat: flags &= ~DISK_REPEAT; - generateStatus(out, true, dev_CMD_SW); + generateStatus(out, true, Device::CMD_SW); out->reaction = r_StatusReport; break; default: break; } +#pragma GCC diagnostic pop } void CDChanger::react(Frame *out, detail::Error::Send err) { @@ -258,8 +274,12 @@ void CDChanger::react(Frame *out, detail::Error::Send err) { } break; case r_Ejection: { - const uint8_t play[] = {0x00, dev_COMM_CTRL, dev_COMM_v1, - Insertion, dev_CD_CHANGER, 0x01}; + const uint8_t play[] = {0x00, + to_underlying(Device::COMM_CTRL), + to_underlying(Device::COMM_v1), + to_underlying(Action::Insertion), + to_underlying(Device::CD_CHANGER), + 0x01}; out->length = sizeof(play); memcpy(out->data, play, sizeof(play)); } @@ -270,8 +290,8 @@ void CDChanger::react(Frame *out, detail::Error::Send err) { out->peripheral_addr = 0x1FF; out->length = sizeof(cdloading_resp) + 1; memcpy(out->data, cdloading_resp, sizeof(cdloading_resp)); - out->data[1] = dev_STATUS; - out->data[2] = Loading_Status_Report; + out->data[1] = to_underlying(Device::STATUS); + out->data[2] = to_underlying(Action::Loading_Status_Report); out->reaction = r_SendOnly; break; case r_TrackChange: @@ -281,12 +301,12 @@ void CDChanger::react(Frame *out, detail::Error::Send err) { [[fallthrough]]; case r_NormalizeState: normalizeState(); - generateStatus(out, true, dev_STATUS); + generateStatus(out, true, Device::STATUS); out->reaction = r_SendOnly; break; case r_StartPlaying: normalizeState(); - generateStatus(out, true, dev_STATUS); + generateStatus(out, true, Device::STATUS); out->reaction = r_BeganPlaying; break; case r_BeganPlaying: @@ -294,7 +314,7 @@ void CDChanger::react(Frame *out, detail::Error::Send err) { out->reaction = r_Nothing; break; case r_StatusReport: - generateStatus(out, true, dev_STATUS); + generateStatus(out, true, Device::STATUS); out->reaction = r_SendOnly; break; case r_SendOnly: [[fallthrough]]; @@ -311,7 +331,7 @@ void CDChanger::enable(Frame *out) { secs = 0; state = SEEKING | SEEKING_TRACK; flags2 = 0xc0; - generateStatus(out, true, dev_STATUS); + generateStatus(out, true, Device::STATUS); out->reaction = r_StartPlaying; } } @@ -321,7 +341,7 @@ void CDChanger::resolvepending() { statustimer_clearTick(); } void CDChanger::emit(Frame *out, uint16_t peripheral) { out->peripheral_addr = peripheral; - generateStatus(out, true, dev_STATUS); + generateStatus(out, true, Device::STATUS); out->reaction = r_StateReport; } @@ -379,7 +399,7 @@ void CDChanger::incrementTime() { // Used for changed status messages void CDChanger::generateStatus(Frame *status, bool is_unicast, - devices to) const { + Device to) const { status->is_unicast = is_unicast; if (!is_unicast) status->peripheral_addr = 0x1FF; @@ -389,9 +409,9 @@ void CDChanger::generateStatus(Frame *status, bool is_unicast, uint8_t *data = status->data; if (is_unicast) *data++ = 0x00; - *data++ = dev_CD_CHANGER; - *data++ = to; - *data++ = Status_Report; + *data++ = to_underlying(Device::CD_CHANGER); + *data++ = to_underlying(to); + *data++ = to_underlying(Action::Status_Report); serialize(data); } diff --git a/src/avclan/cdchanger.hpp b/src/avclan/cdchanger.hpp index 72ee47c..e8a24f5 100644 --- a/src/avclan/cdchanger.hpp +++ b/src/avclan/cdchanger.hpp @@ -8,7 +8,7 @@ #include #include "avclan.h" -#include "avclan_defs.h" +#include "device.hpp" #include "frame.hpp" namespace avclan { @@ -57,7 +57,7 @@ public: r_StateReport, // *IS* a status report (follow-up or unprompted) }; - static constexpr uint8_t id = dev_CD_CHANGER; + static constexpr Device id = Device::CD_CHANGER; void init(); void handle(const Frame *in, Frame *out); @@ -75,7 +75,7 @@ private: void stopPlaying(); void serialize(uint8_t *dst) const; void setTime(uint8_t mins, uint8_t secs); - void generateStatus(Frame *status, bool is_unicast, devices to) const; + void generateStatus(Frame *status, bool is_unicast, Device to) const; void normalizeState(); bool playing = false; diff --git a/src/avclan/device.hpp b/src/avclan/device.hpp index 4c0f996..1351f87 100644 --- a/src/avclan/device.hpp +++ b/src/avclan/device.hpp @@ -3,23 +3,44 @@ #pragma once -#include "avclan.h" -#include "frame.hpp" - #include #include +#include "avclan.h" +#include "frame.hpp" + namespace avclan { + +enum class Device : uint8_t { + LAN = 0x00, + COMM_CTRL = 0x01, + COMM_v1 = 0x11, + COMM_v2 = 0x12, + SW = 0x21, + SW_NAME = 0x23, + SW_CONVERTING = 0x24, + CMD_SW = 0x25, + STATUS = 0x31, + BEEP_HU = 0x28, + BEEP_SPEAKERS = 0x29, + TUNER = 0x60, + TAPE_DECK = 0x61, + CD = 0x62, + CD_CHANGER = 0x63, + AUDIO_AMP = 0x74, +}; + template -concept Device = requires { std::integral_constant{}; } && - requires(T dev, const Frame *in, Frame *out, - detail::Error::Send err, uint16_t peripheral) { - dev.init(); - dev.handle(in, out); - dev.enable(out); - dev.react(out, err); - { dev.pending() } -> std::convertible_to; - dev.resolvepending(); - dev.emit(out, peripheral); - }; +concept DeviceInterface = + requires { std::integral_constant{}; } && + requires(T dev, const Frame *in, Frame *out, detail::Error::Send err, + uint16_t peripheral) { + dev.init(); + dev.handle(in, out); + dev.enable(out); + dev.react(out, err); + { dev.pending() } -> std::convertible_to; + dev.resolvepending(); + dev.emit(out, peripheral); + }; } // namespace avclan diff --git a/src/avclan/frame.hpp b/src/avclan/frame.hpp index 307bbdd..88c0448 100644 --- a/src/avclan/frame.hpp +++ b/src/avclan/frame.hpp @@ -8,6 +8,8 @@ #include namespace avclan { +enum class Device : uint8_t; + struct Frame { struct Print { bool print : 1 = false; // print at all @@ -27,7 +29,7 @@ struct Frame { void print(Print print) const; uint8_t reaction; - uint8_t owning_device; + Device owning_device; bool is_unicast; uint16_t controller_addr; // formerly "master" uint16_t peripheral_addr; // formerly "slave" diff --git a/src/avclan/peripheral.hpp b/src/avclan/peripheral.hpp index 4f7df40..6243532 100644 --- a/src/avclan/peripheral.hpp +++ b/src/avclan/peripheral.hpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #pragma once -#include "avclan_defs.h" +#include "avclan.h" #include "bus.hpp" #include "device.hpp" #include "frame.hpp" @@ -14,7 +14,7 @@ #include namespace avclan { -template class Peripheral { +template class Peripheral { public: using Error = detail::Error; @@ -38,6 +38,8 @@ public: #define PACK3(a, b, c) (((uint32_t)(a) << 16) | ((uint32_t)(b) << 8) | (c)) void route(const Frame *in, Frame *out) { + using enum Device; + using enum Action; out->reaction = 0; if (AVCLAN_ismuted() || in->length < 3) @@ -45,8 +47,8 @@ public: // 0xFF placeholders are variant bytes filled by writing directly to // out->data[N] after memcpy. - static const uint8_t lancheck_resp[] = {0x00, dev_COMM_CTRL, dev_LAN, 0xFF, - 0xFF}; + static const uint8_t lancheck_resp[] = {0x00, to_underlying(COMM_CTRL), + to_underlying(LAN), 0xFF, 0xFF}; out->peripheral_addr = controller_; @@ -62,51 +64,58 @@ public: // Broadcast: bytes are (from, to, action, [extra...]). // peripheral_addr unchecked — always 0xFFF or 0x1FF in known traffic. switch (PACK3(b0, b1, b2)) { - case PACK3(dev_LAN, dev_COMM_CTRL, Lancheck_Scan_Req): + case PACK3(LAN, COMM_CTRL, to_underlying(Lancheck_Scan_Req)): out->length = sizeof(lancheck_resp); out->is_unicast = true; memcpy(out->data, lancheck_resp, sizeof(lancheck_resp)); - out->data[3] = Lancheck_Scan_Resp; + out->data[3] = to_underlying(Lancheck_Scan_Resp); out->data[4] = 0x01; out->reaction = 1; break; - case PACK3(dev_LAN, dev_COMM_CTRL, Lancheck_Req): + case PACK3(LAN, COMM_CTRL, to_underlying(Lancheck_Req)): out->length = sizeof(lancheck_resp); out->is_unicast = true; memcpy(out->data, lancheck_resp, sizeof(lancheck_resp)); - out->data[3] = Lancheck_Resp; + out->data[3] = to_underlying(Lancheck_Resp); out->data[4] = 0x00; out->reaction = 1; break; - case PACK3(dev_LAN, dev_COMM_CTRL, Lancheck_End_Req): + case PACK3(LAN, COMM_CTRL, to_underlying(Lancheck_End_Req)): out->is_unicast = true; out->length = sizeof(lancheck_resp) - 1; memcpy(out->data, lancheck_resp, out->length); - out->data[3] = Lancheck_End_Resp; + out->data[3] = to_underlying(Lancheck_End_Resp); out->reaction = 1; break; - case PACK3(dev_COMM_v1, dev_COMM_CTRL, Current_Function): - case PACK3(dev_COMM_v2, dev_COMM_CTRL, Current_Function): - ((Devs::id == b3 ? std::get(devices_).enable(out), 0 : 0), ...); + case PACK3(COMM_v1, COMM_CTRL, to_underlying(Current_Function)): + case PACK3(COMM_v2, COMM_CTRL, to_underlying(Current_Function)): + ((Devs::id == static_cast(b3) + ? std::get(devices_).enable(out), + 0 : 0), + ...); break; - case PACK3(dev_COMM_v1, dev_COMM_CTRL, Ping_Req): - case PACK3(dev_COMM_v2, dev_COMM_CTRL, Ping_Req): { + case PACK3(COMM_v1, COMM_CTRL, to_underlying(Ping_Req)): + case PACK3(COMM_v2, COMM_CTRL, to_underlying(Ping_Req)): { out->is_unicast = true; - const uint8_t ping_resp[] = {0x00, dev_COMM_CTRL, dev_COMM_v1, - Ping_Resp, 0xFF, b3}; + const uint8_t ping_resp[] = {0x00, + to_underlying(COMM_CTRL), + to_underlying(COMM_v1), + to_underlying(Ping_Resp), + 0xFF, + b3}; out->length = sizeof(ping_resp); memcpy(out->data, ping_resp, sizeof(ping_resp)); out->reaction = 1; break; } - case PACK3(dev_COMM_v1, dev_COMM_CTRL, List_Functions_Req): - case PACK3(dev_COMM_v2, dev_COMM_CTRL, List_Functions_Req): { + case PACK3(COMM_v1, COMM_CTRL, to_underlying(List_Functions_Req)): + case PACK3(COMM_v2, COMM_CTRL, to_underlying(List_Functions_Req)): { controller_ = in->controller_addr; out->peripheral_addr = controller_; out->is_unicast = true; const uint8_t list_functions_resp[] = { - 0x00, dev_COMM_CTRL, dev_COMM_v1, List_Functions_Resp, - dev_CD_CHANGER}; + 0x00, to_underlying(COMM_CTRL), to_underlying(COMM_v1), + to_underlying(List_Functions_Resp), to_underlying(CD_CHANGER)}; out->length = sizeof(list_functions_resp); memcpy(out->data, list_functions_resp, sizeof(list_functions_resp)); out->reaction = 1; @@ -115,8 +124,9 @@ public: // case Restart_Lan: not handled } } else if (in->peripheral_addr == address_ && b0 == 0x00) { - ((Devs::id == b2 ? device_preroute(std::get(devices_), in, out), - 0 : 0), + ((Devs::id == static_cast(b2) + ? device_preroute(std::get(devices_), in, out), + 0 : 0), ...); } } @@ -143,11 +153,11 @@ private: out->control = 0xF; } - template void poller(Dev &dev, F &&fun) { + template void poller(Dev &dev, F &&fun) { if (dev.pending() && fun(dev)) dev.resolvepending(); } - template + template 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 5950f03..1724074 100644 --- a/src/sniffer.cc +++ b/src/sniffer.cc @@ -66,6 +66,8 @@ int main() { uint8_t seqIdx = 0; // current index in data_tmp Bus phy; + using enum Action; + using enum Device; Peripheral peripheral(phy, 0x360); using Error = decltype(peripheral)::Error; using Print = Frame::Print; @@ -139,22 +141,27 @@ int main() { out->is_unicast = true; out->peripheral_addr = peripheral.controller(); { - const uint8_t beep[] = {0x00, dev_CD_CHANGER, dev_BEEP_SPEAKERS, - 0x60, 0x01}; + const uint8_t beep[] = {0x00, to_underlying(CD_CHANGER), + to_underlying(BEEP_SPEAKERS), 0x60, 0x01}; out->length = sizeof(beep); memcpy(out->data, beep, sizeof(beep)); } out->reaction = 1; outgoing.push(std::move(out)); - } + } else + RS232_Print("!! Cache empty; unable to queue beep request"); break; case 'P': if (auto out = cache.pop()) { out->is_unicast = true; out->peripheral_addr = peripheral.controller(); { - const uint8_t play[] = {0x00, dev_COMM_CTRL, dev_COMM_v1, - Ejection, dev_CD_CHANGER, 0x01}; + const uint8_t play[] = {0x00, + to_underlying(COMM_CTRL), + to_underlying(COMM_v1), + to_underlying(Ejection), + to_underlying(CD_CHANGER), + 0x01}; out->length = sizeof(play); memcpy(out->data, play, sizeof(play)); }