Fully implement callback logic

This commit is contained in:
GHOSCHT 2023-03-13 13:34:45 +01:00
parent fac5ec5e83
commit da9c24c339
2 changed files with 267 additions and 31 deletions

View file

@ -1,7 +1,48 @@
#include "Parser.h" #include "Parser.h"
#include <etl/vector.h>
message::parser::StateVisitor::StateVisitor(etl::byte_stream_reader &sreader) message::parser::StateVisitor::StateVisitor(
: stream{sreader} {} etl::byte_stream_reader &&sreader,
etl::function<void, etl::string_view> invalidCallback,
etl::function<void, etl::span<const char>> messageLightDataCallback,
etl::function<void, etl::span<const char>> messageInfoCallback,
etl::function<void, etl::span<const char>> messageWarningCallback,
etl::function<void, etl::span<const char>> messageErrorCallback,
etl::function<void, etl::span<const char>> messageSuccessCallback,
etl::function<void, uint32_t> settingsSetBaudCallback,
etl::function<void, etl::span<const char>> settingsWifiPasswordCallback,
etl::function<void, etl::span<const char>> settingsWifiSSIDCallback,
etl::function<void, void> lightControlOnCallback,
etl::function<void, void> lightControlOffCallback,
etl::function<void, uint8_t> lightControlToggleCallback,
etl::function<void, uint8_t> lightControlIncreaseCallback,
etl::function<void, uint8_t> lightControlDecreaseCallback,
etl::function<void, void> commandRequestLightDataCallback,
etl::function<void, void> commandEnterConsoleFlashingCallback,
etl::function<void, void> commandExitConsoleFlashingCallback,
etl::function<void, void> commandPairBluetoothCallback,
etl::function<void, void> commandHelpCallback,
etl::function<void, void> commandVersionCallback)
: stream{etl::move(sreader)}, invalidCallback{invalidCallback},
messageLightDataCallback{messageLightDataCallback},
messageInfoCallback{messageInfoCallback},
messageWarningCallback{messageWarningCallback},
messageErrorCallback{messageErrorCallback},
messageSuccessCallback{messageSuccessCallback},
settingsSetBaudCallback{settingsSetBaudCallback},
settingsWifiPasswordCallback{settingsWifiPasswordCallback},
settingsWifiSSIDCallback{settingsWifiSSIDCallback},
lightControlOnCallback{lightControlOnCallback},
lightControlOffCallback{lightControlOffCallback},
lightControlToggleCallback{lightControlToggleCallback},
lightControlIncreaseCallback{lightControlIncreaseCallback},
lightControlDecreaseCallback{lightControlDecreaseCallback},
commandRequestLightDataCallback{commandRequestLightDataCallback},
commandEnterConsoleFlashingCallback{commandEnterConsoleFlashingCallback},
commandExitConsoleFlashingCallback{commandExitConsoleFlashingCallback},
commandPairBluetoothCallback{commandPairBluetoothCallback},
commandHelpCallback{commandHelpCallback}, commandVersionCallback{
commandVersionCallback} {}
auto message::parser::StateVisitor::operator()(state::ModeSelection) -> State { auto message::parser::StateVisitor::operator()(state::ModeSelection) -> State {
if (!stream.available<uint8_t>()) { if (!stream.available<uint8_t>()) {
@ -58,25 +99,76 @@ auto message::parser::StateVisitor::operator()(state::Message) -> State {
return state::Invalid{}; return state::Invalid{};
} }
} }
auto message::parser::StateVisitor::operator()(state::MessageLightData) auto message::parser::StateVisitor::operator()(state::MessageLightData)
-> State { -> State {
messageLightDataCallback(); if (!stream.available<char>()) {
invalidCallback("MessageLightData: Stream not available");
return state::Invalid{};
}
auto msg = stream.read<char>(stream.available<char>());
if (!msg.has_value()) {
invalidCallback("MessageLightData: Message has no value");
return state::Invalid{};
}
messageLightDataCallback(msg.value());
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::MessageInfo) -> State { auto message::parser::StateVisitor::operator()(state::MessageInfo) -> State {
messageInfoCallback(); if (!stream.available<char>()) {
invalidCallback("MessageInfo: Stream not available");
return state::Invalid{};
}
auto msg = stream.read<char>(stream.available<char>());
if (!msg.has_value()) {
invalidCallback("MessageInfo: Message has no value");
return state::Invalid{};
}
messageInfoCallback(msg.value());
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::MessageWarning) -> State { auto message::parser::StateVisitor::operator()(state::MessageWarning) -> State {
messageWarningCallback(); if (!stream.available<char>()) {
invalidCallback("MessageWarning: Stream not available");
return state::Invalid{};
}
auto msg = stream.read<char>(stream.available<char>());
if (!msg.has_value()) {
invalidCallback("MessageWarning: Message has no value");
return state::Invalid{};
}
messageWarningCallback(msg.value());
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::MessageError) -> State { auto message::parser::StateVisitor::operator()(state::MessageError) -> State {
messageErrorCallback(); if (!stream.available<char>()) {
invalidCallback("MessageError: Stream not available");
return state::Invalid{};
}
auto msg = stream.read<char>(stream.available<char>());
if (!msg.has_value()) {
invalidCallback("MessageError: Message has no value");
return state::Invalid{};
}
messageErrorCallback(msg.value());
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::MessageSuccess) -> State { auto message::parser::StateVisitor::operator()(state::MessageSuccess) -> State {
messageSuccessCallback(); if (!stream.available<char>()) {
invalidCallback("MessageSuccess: Stream not available");
return state::Invalid{};
}
auto msg = stream.read<char>(stream.available<char>());
if (!msg.has_value()) {
invalidCallback("MessageSuccess: Message has no value");
return state::Invalid{};
}
messageSuccessCallback(msg.value());
return state::Complete{}; return state::Complete{};
} }
@ -106,17 +198,51 @@ auto message::parser::StateVisitor::operator()(state::Settings) -> State {
} }
auto message::parser::StateVisitor::operator()(state::SettingsSetBaud) auto message::parser::StateVisitor::operator()(state::SettingsSetBaud)
-> State { -> State {
settingsSetBaudCallback(); if (!stream.available<uint32_t>()) {
invalidCallback("Settings: Stream not available");
return state::Invalid{};
}
auto baud = stream.read<uint32_t>();
if (!baud.has_value()) {
invalidCallback("SettingsSetBaud: Baud has no value");
return state::Invalid{};
}
settingsSetBaudCallback(baud.value());
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::SettingsWifiPassword) auto message::parser::StateVisitor::operator()(state::SettingsWifiPassword)
-> State { -> State {
settingsWifiPasswordCallback(); if (!stream.available<char>()) {
invalidCallback("SettingsWifiPassword: Stream not available");
return state::Invalid{};
}
auto passwd = stream.read<char>(stream.available<char>());
if (!passwd.has_value()) {
invalidCallback("SettingsWifiPassword: Passwd has no value");
return state::Invalid{};
}
settingsWifiPasswordCallback(passwd.value());
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::SettingsWifiSSID) auto message::parser::StateVisitor::operator()(state::SettingsWifiSSID)
-> State { -> State {
settingsWifiSSIDCallback(); if (!stream.available<char>()) {
invalidCallback("SettingsWifiSSID: Stream not available");
return state::Invalid{};
}
auto ssid = stream.read<char>(stream.available<char>());
if (!ssid.has_value()) {
invalidCallback("SettingsWifiSSID: SSID has no value");
return state::Invalid{};
}
settingsWifiSSIDCallback(ssid.value());
return state::Complete{}; return state::Complete{};
} }
@ -171,8 +297,14 @@ auto message::parser::StateVisitor::operator()(state::LightControlToggle)
if (stream.available_bytes() > 1) { if (stream.available_bytes() > 1) {
invalidCallback("LightControlToggle: Too many bytes left"); invalidCallback("LightControlToggle: Too many bytes left");
return state::Invalid{}; return state::Invalid{};
} else if (!stream.available<uint8_t>()) {
invalidCallback("LightControlToggle: Stream not available");
return state::Invalid{};
} }
lightControlToggleCallback();
auto id = stream.read<uint8_t>();
lightControlToggleCallback(id.value());
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::LightControlIncrease) auto message::parser::StateVisitor::operator()(state::LightControlIncrease)
@ -180,8 +312,14 @@ auto message::parser::StateVisitor::operator()(state::LightControlIncrease)
if (stream.available_bytes() > 1) { if (stream.available_bytes() > 1) {
invalidCallback("LightControlIncrease: Too many bytes left"); invalidCallback("LightControlIncrease: Too many bytes left");
return state::Invalid{}; return state::Invalid{};
} else if (!stream.available<uint8_t>()) {
invalidCallback("LightControlIncrease: Stream not available");
return state::Invalid{};
} }
lightControlIncreaseCallback();
auto id = stream.read<uint8_t>();
lightControlIncreaseCallback(id.value());
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::LightControlDecrease) auto message::parser::StateVisitor::operator()(state::LightControlDecrease)
@ -189,8 +327,14 @@ auto message::parser::StateVisitor::operator()(state::LightControlDecrease)
if (stream.available_bytes() > 1) { if (stream.available_bytes() > 1) {
invalidCallback("LightControlDecrease: Too many bytes left"); invalidCallback("LightControlDecrease: Too many bytes left");
return state::Invalid{}; return state::Invalid{};
} else if (!stream.available<uint8_t>()) {
invalidCallback("LightControlDecrease: Stream not available");
return state::Invalid{};
} }
lightControlDecreaseCallback();
auto id = stream.read<uint8_t>();
lightControlDecreaseCallback(id.value());
return state::Complete{}; return state::Complete{};
} }
@ -257,10 +401,20 @@ auto message::parser::StateVisitor::operator()(state::CommandPairBluetooth)
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::CommandHelp) -> State { auto message::parser::StateVisitor::operator()(state::CommandHelp) -> State {
if (stream.available_bytes() > 0) {
invalidCallback("CommandHelp: Too many bytes left");
return state::Invalid{};
}
commandHelpCallback(); commandHelpCallback();
return state::Complete{}; return state::Complete{};
} }
auto message::parser::StateVisitor::operator()(state::CommandVersion) -> State { auto message::parser::StateVisitor::operator()(state::CommandVersion) -> State {
if (stream.available_bytes() > 0) {
invalidCallback("CommandVersion: Too many bytes left");
return state::Invalid{};
}
commandVersionCallback(); commandVersionCallback();
return state::Complete{}; return state::Complete{};
} }
@ -272,14 +426,52 @@ auto message::parser::StateVisitor::operator()(state::Invalid) -> State {
return state::Invalid{}; return state::Invalid{};
} }
auto message::parser::parse(etl::byte_stream_reader &reader) -> void { auto message::parser::parse(
StateVisitor visitor{reader}; etl::byte_stream_reader &&reader,
etl::function<void, etl::string_view> invalidCallback,
etl::function<void, etl::span<const char>> messageLightDataCallback,
etl::function<void, etl::span<const char>> messageInfoCallback,
etl::function<void, etl::span<const char>> messageWarningCallback,
etl::function<void, etl::span<const char>> messageErrorCallback,
etl::function<void, etl::span<const char>> messageSuccessCallback,
etl::function<void, uint32_t> settingsSetBaudCallback,
etl::function<void, etl::span<const char>> settingsWifiPasswordCallback,
etl::function<void, etl::span<const char>> settingsWifiSSIDCallback,
etl::function<void, void> lightControlOnCallback,
etl::function<void, void> lightControlOffCallback,
etl::function<void, uint8_t> lightControlToggleCallback,
etl::function<void, uint8_t> lightControlIncreaseCallback,
etl::function<void, uint8_t> lightControlDecreaseCallback,
etl::function<void, void> commandRequestLightDataCallback,
etl::function<void, void> commandEnterConsoleFlashingCallback,
etl::function<void, void> commandExitConsoleFlashingCallback,
etl::function<void, void> commandPairBluetoothCallback,
etl::function<void, void> commandHelpCallback,
etl::function<void, void> commandVersionCallback) -> void {
StateVisitor visitor{etl::move(reader),
invalidCallback,
messageLightDataCallback,
messageInfoCallback,
messageWarningCallback,
messageErrorCallback,
messageSuccessCallback,
settingsSetBaudCallback,
settingsWifiPasswordCallback,
settingsWifiSSIDCallback,
lightControlOnCallback,
lightControlOffCallback,
lightControlToggleCallback,
lightControlIncreaseCallback,
lightControlDecreaseCallback,
commandRequestLightDataCallback,
commandEnterConsoleFlashingCallback,
commandExitConsoleFlashingCallback,
commandPairBluetoothCallback,
commandHelpCallback,
commandVersionCallback};
State state{state::ModeSelection{}}; State state{state::ModeSelection{}};
while (!etl::holds_alternative<state::Invalid>(state) && while (!etl::holds_alternative<state::Invalid>(state) &&
!etl::holds_alternative<state::Complete>(state)) { !etl::holds_alternative<state::Complete>(state)) {
state = etl::visit(visitor, state); state = etl::visit(visitor, state);
} }
if (etl::holds_alternative<state::Invalid>(state)) {
// TODO: error
}
} }

View file

@ -2,6 +2,8 @@
#include "Protocol.h" #include "Protocol.h"
#include <etl/byte_stream.h> #include <etl/byte_stream.h>
#include <etl/function.h> #include <etl/function.h>
#include <etl/span.h>
#include <etl/string_view.h>
#include <etl/variant.h> #include <etl/variant.h>
namespace message { namespace message {
@ -47,11 +49,53 @@ using State = etl::variant<
state::CommandExitConsoleFlashing, state::CommandPairBluetooth, state::CommandExitConsoleFlashing, state::CommandPairBluetooth,
state::CommandHelp, state::CommandVersion, state::Complete>; state::CommandHelp, state::CommandVersion, state::Complete>;
void parse(etl::byte_stream_reader &reader); void parse(
etl::byte_stream_reader &&reader,
etl::function<void, etl::string_view> invalidCallback,
etl::function<void, etl::span<const char>> messageLightDataCallback,
etl::function<void, etl::span<const char>> messageInfoCallback,
etl::function<void, etl::span<const char>> messageWarningCallback,
etl::function<void, etl::span<const char>> messageErrorCallback,
etl::function<void, etl::span<const char>> messageSuccessCallback,
etl::function<void, uint32_t> settingsSetBaudCallback,
etl::function<void, etl::span<const char>> settingsWifiPasswordCallback,
etl::function<void, etl::span<const char>> settingsWifiSSIDCallback,
etl::function<void, void> lightControlOnCallback,
etl::function<void, void> lightControlOffCallback,
etl::function<void, uint8_t> lightControlToggleCallback,
etl::function<void, uint8_t> lightControlIncreaseCallback,
etl::function<void, uint8_t> lightControlDecreaseCallback,
etl::function<void, void> commandRequestLightDataCallback,
etl::function<void, void> commandEnterConsoleFlashingCallback,
etl::function<void, void> commandExitConsoleFlashingCallback,
etl::function<void, void> commandPairBluetoothCallback,
etl::function<void, void> commandHelpCallback,
etl::function<void, void> commandVersionCallback);
class StateVisitor { class StateVisitor {
public: public:
StateVisitor(etl::byte_stream_reader &); StateVisitor(
etl::byte_stream_reader &&sreader,
etl::function<void, etl::string_view> invalidCallback,
etl::function<void, etl::span<const char>> messageLightDataCallback,
etl::function<void, etl::span<const char>> messageInfoCallback,
etl::function<void, etl::span<const char>> messageWarningCallback,
etl::function<void, etl::span<const char>> messageErrorCallback,
etl::function<void, etl::span<const char>> messageSuccessCallback,
etl::function<void, uint32_t> settingsSetBaudCallback,
etl::function<void, etl::span<const char>> settingsWifiPasswordCallback,
etl::function<void, etl::span<const char>> settingsWifiSSIDCallback,
etl::function<void, void> lightControlOnCallback,
etl::function<void, void> lightControlOffCallback,
etl::function<void, uint8_t> lightControlToggleCallback,
etl::function<void, uint8_t> lightControlIncreaseCallback,
etl::function<void, uint8_t> lightControlDecreaseCallback,
etl::function<void, void> commandRequestLightDataCallback,
etl::function<void, void> commandEnterConsoleFlashingCallback,
etl::function<void, void> commandExitConsoleFlashingCallback,
etl::function<void, void> commandPairBluetoothCallback,
etl::function<void, void> commandHelpCallback,
etl::function<void, void> commandVersionCallback);
State operator()(state::ModeSelection); State operator()(state::ModeSelection);
State operator()(state::Message); State operator()(state::Message);
State operator()(state::MessageLightData); State operator()(state::MessageLightData);
@ -86,19 +130,19 @@ private:
etl::byte_stream_reader stream; etl::byte_stream_reader stream;
// TODO: callback function parameter types // TODO: callback function parameter types
etl::function<void, etl::string_view> invalidCallback; etl::function<void, etl::string_view> invalidCallback;
etl::function<void, void> messageLightDataCallback; etl::function<void, etl::span<const char>> messageLightDataCallback;
etl::function<void, void> messageInfoCallback; etl::function<void, etl::span<const char>> messageInfoCallback;
etl::function<void, void> messageWarningCallback; etl::function<void, etl::span<const char>> messageWarningCallback;
etl::function<void, void> messageErrorCallback; etl::function<void, etl::span<const char>> messageErrorCallback;
etl::function<void, void> messageSuccessCallback; etl::function<void, etl::span<const char>> messageSuccessCallback;
etl::function<void, void> settingsSetBaudCallback; etl::function<void, uint32_t> settingsSetBaudCallback;
etl::function<void, void> settingsWifiPasswordCallback; etl::function<void, etl::span<const char>> settingsWifiPasswordCallback;
etl::function<void, void> settingsWifiSSIDCallback; etl::function<void, etl::span<const char>> settingsWifiSSIDCallback;
etl::function<void, void> lightControlOnCallback; etl::function<void, void> lightControlOnCallback;
etl::function<void, void> lightControlOffCallback; etl::function<void, void> lightControlOffCallback;
etl::function<void, void> lightControlToggleCallback; etl::function<void, uint8_t> lightControlToggleCallback;
etl::function<void, void> lightControlIncreaseCallback; etl::function<void, uint8_t> lightControlIncreaseCallback;
etl::function<void, void> lightControlDecreaseCallback; etl::function<void, uint8_t> lightControlDecreaseCallback;
etl::function<void, void> commandRequestLightDataCallback; etl::function<void, void> commandRequestLightDataCallback;
etl::function<void, void> commandEnterConsoleFlashingCallback; etl::function<void, void> commandEnterConsoleFlashingCallback;
etl::function<void, void> commandExitConsoleFlashingCallback; etl::function<void, void> commandExitConsoleFlashingCallback;