diff --git a/include/CommandHandler.h b/include/CommandHandler.h index 26e35981..8364b9a6 100644 --- a/include/CommandHandler.h +++ b/include/CommandHandler.h @@ -1,5 +1,7 @@ #pragma once +#include "ShockerCommandType.h" + #include // TODO: This is bad architecture. Fix it. @@ -7,7 +9,7 @@ namespace OpenShock::CommandHandler { void Init(); bool HandleCommand(std::uint16_t shockerId, - std::uint8_t method, + OpenShock::ShockerCommandType type, std::uint8_t intensity, unsigned int duration, std::uint8_t shockerModel); diff --git a/include/RFTransmitter.h b/include/RFTransmitter.h index 06bc825a..43fc3259 100644 --- a/include/RFTransmitter.h +++ b/include/RFTransmitter.h @@ -1,5 +1,7 @@ #pragma once +#include "ShockerCommandType.h" + #include // Forward definitions to remove clutter @@ -19,7 +21,7 @@ namespace OpenShock { bool SendCommand(std::uint8_t shockerModel, std::uint16_t shockerId, - std::uint8_t method, + OpenShock::ShockerCommandType type, std::uint8_t intensity, unsigned int duration); void ClearPendingCommands(); diff --git a/include/Rmt/MainEncoder.h b/include/Rmt/MainEncoder.h index 2a58a15c..9c857fc3 100644 --- a/include/Rmt/MainEncoder.h +++ b/include/Rmt/MainEncoder.h @@ -1,5 +1,7 @@ #pragma once +#include "ShockerCommandType.h" + #include #include @@ -8,6 +10,6 @@ namespace OpenShock::Rmt { std::vector - GetSequence(std::uint16_t shockerId, std::uint8_t method, std::uint8_t intensity, std::uint8_t shockerModel); + GetSequence(std::uint16_t shockerId, OpenShock::ShockerCommandType type, std::uint8_t intensity, std::uint8_t shockerModel); std::shared_ptr> GetZeroSequence(std::uint16_t shockerId, std::uint8_t shockerModel); } diff --git a/include/Rmt/PetTrainerEncoder.h b/include/Rmt/PetTrainerEncoder.h index 5ed45cce..1679cb63 100644 --- a/include/Rmt/PetTrainerEncoder.h +++ b/include/Rmt/PetTrainerEncoder.h @@ -1,10 +1,12 @@ #pragma once +#include "ShockerCommandType.h" + #include #include #include namespace OpenShock::Rmt::PetTrainerEncoder { - std::vector GetSequence(std::uint16_t shockerId, std::uint8_t method, std::uint8_t intensity); + std::vector GetSequence(std::uint16_t shockerId, OpenShock::ShockerCommandType type, std::uint8_t intensity); } diff --git a/include/Rmt/XlcEncoder.h b/include/Rmt/XlcEncoder.h index 5c1d0aea..ca36d14b 100644 --- a/include/Rmt/XlcEncoder.h +++ b/include/Rmt/XlcEncoder.h @@ -1,11 +1,15 @@ #pragma once +#include "ShockerCommandType.h" + #include #include #include namespace OpenShock::Rmt::XlcEncoder { - std::vector - GetSequence(std::uint16_t transmitterId, std::uint8_t channelId, std::uint8_t method, std::uint8_t intensity); + std::vector GetSequence(std::uint16_t transmitterId, + std::uint8_t channelId, + OpenShock::ShockerCommandType type, + std::uint8_t intensity); } diff --git a/include/ShockerCommandType.h b/include/ShockerCommandType.h new file mode 100644 index 00000000..82f0f316 --- /dev/null +++ b/include/ShockerCommandType.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace OpenShock { + + enum ShockerCommandType : std::uint8_t { + Stop = 0, + Shock = 1, + Vibrate = 2, + Sound = 3, + }; + +} // namespace OpenShock diff --git a/include/fbs/ServerMessages_generated.h b/include/fbs/ServerMessages_generated.h new file mode 100644 index 00000000..f38c7bd2 --- /dev/null +++ b/include/fbs/ServerMessages_generated.h @@ -0,0 +1,350 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_SERVERMESSAGES_OPENSHOCK_SERIALIZATION_H_ +#define FLATBUFFERS_GENERATED_SERVERMESSAGES_OPENSHOCK_SERIALIZATION_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 23 && + FLATBUFFERS_VERSION_MINOR == 5 && + FLATBUFFERS_VERSION_REVISION == 26, + "Non-compatible flatbuffers version included"); + +namespace OpenShock { +namespace Serialization { + +struct ShockerCommand; + +struct ShockerCommandList; +struct ShockerCommandListBuilder; + +struct CaptivePortalConfig; + +struct ServerMessage; +struct ServerMessageBuilder; + +enum ShockerCommandType : uint8_t { + ShockerCommandType_Stop = 0, + ShockerCommandType_Shock = 1, + ShockerCommandType_Vibrate = 2, + ShockerCommandType_Sound = 3, + ShockerCommandType_MIN = ShockerCommandType_Stop, + ShockerCommandType_MAX = ShockerCommandType_Sound +}; + +inline const ShockerCommandType (&EnumValuesShockerCommandType())[4] { + static const ShockerCommandType values[] = { + ShockerCommandType_Stop, + ShockerCommandType_Shock, + ShockerCommandType_Vibrate, + ShockerCommandType_Sound + }; + return values; +} + +inline const char * const *EnumNamesShockerCommandType() { + static const char * const names[5] = { + "Stop", + "Shock", + "Vibrate", + "Sound", + nullptr + }; + return names; +} + +inline const char *EnumNameShockerCommandType(ShockerCommandType e) { + if (::flatbuffers::IsOutRange(e, ShockerCommandType_Stop, ShockerCommandType_Sound)) return ""; + const size_t index = static_cast(e); + return EnumNamesShockerCommandType()[index]; +} + +enum ServerMessagePayload : uint8_t { + ServerMessagePayload_NONE = 0, + ServerMessagePayload_ShockerCommandList = 1, + ServerMessagePayload_CaptivePortalConfig = 2, + ServerMessagePayload_MIN = ServerMessagePayload_NONE, + ServerMessagePayload_MAX = ServerMessagePayload_CaptivePortalConfig +}; + +inline const ServerMessagePayload (&EnumValuesServerMessagePayload())[3] { + static const ServerMessagePayload values[] = { + ServerMessagePayload_NONE, + ServerMessagePayload_ShockerCommandList, + ServerMessagePayload_CaptivePortalConfig + }; + return values; +} + +inline const char * const *EnumNamesServerMessagePayload() { + static const char * const names[4] = { + "NONE", + "ShockerCommandList", + "CaptivePortalConfig", + nullptr + }; + return names; +} + +inline const char *EnumNameServerMessagePayload(ServerMessagePayload e) { + if (::flatbuffers::IsOutRange(e, ServerMessagePayload_NONE, ServerMessagePayload_CaptivePortalConfig)) return ""; + const size_t index = static_cast(e); + return EnumNamesServerMessagePayload()[index]; +} + +template struct ServerMessagePayloadTraits { + static const ServerMessagePayload enum_value = ServerMessagePayload_NONE; +}; + +template<> struct ServerMessagePayloadTraits { + static const ServerMessagePayload enum_value = ServerMessagePayload_ShockerCommandList; +}; + +template<> struct ServerMessagePayloadTraits { + static const ServerMessagePayload enum_value = ServerMessagePayload_CaptivePortalConfig; +}; + +bool VerifyServerMessagePayload(::flatbuffers::Verifier &verifier, const void *obj, ServerMessagePayload type); +bool VerifyServerMessagePayloadVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types); + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) ShockerCommand FLATBUFFERS_FINAL_CLASS { + private: + uint8_t model_; + uint8_t id_; + uint8_t type_; + uint8_t intensity_; + uint32_t duration_; + + public: + ShockerCommand() + : model_(0), + id_(0), + type_(0), + intensity_(0), + duration_(0) { + } + ShockerCommand(uint8_t _model, uint8_t _id, OpenShock::Serialization::ShockerCommandType _type, uint8_t _intensity, uint32_t _duration) + : model_(::flatbuffers::EndianScalar(_model)), + id_(::flatbuffers::EndianScalar(_id)), + type_(::flatbuffers::EndianScalar(static_cast(_type))), + intensity_(::flatbuffers::EndianScalar(_intensity)), + duration_(::flatbuffers::EndianScalar(_duration)) { + } + uint8_t model() const { + return ::flatbuffers::EndianScalar(model_); + } + uint8_t id() const { + return ::flatbuffers::EndianScalar(id_); + } + OpenShock::Serialization::ShockerCommandType type() const { + return static_cast(::flatbuffers::EndianScalar(type_)); + } + uint8_t intensity() const { + return ::flatbuffers::EndianScalar(intensity_); + } + uint32_t duration() const { + return ::flatbuffers::EndianScalar(duration_); + } +}; +FLATBUFFERS_STRUCT_END(ShockerCommand, 8); + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(1) CaptivePortalConfig FLATBUFFERS_FINAL_CLASS { + private: + uint8_t enabled_; + + public: + CaptivePortalConfig() + : enabled_(0) { + } + CaptivePortalConfig(bool _enabled) + : enabled_(::flatbuffers::EndianScalar(static_cast(_enabled))) { + } + bool enabled() const { + return ::flatbuffers::EndianScalar(enabled_) != 0; + } +}; +FLATBUFFERS_STRUCT_END(CaptivePortalConfig, 1); + +struct ShockerCommandList FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ShockerCommandListBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_COMMANDS = 4 + }; + const ::flatbuffers::Vector *commands() const { + return GetPointer *>(VT_COMMANDS); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_COMMANDS) && + verifier.VerifyVector(commands()) && + verifier.EndTable(); + } +}; + +struct ShockerCommandListBuilder { + typedef ShockerCommandList Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_commands(::flatbuffers::Offset<::flatbuffers::Vector> commands) { + fbb_.AddOffset(ShockerCommandList::VT_COMMANDS, commands); + } + explicit ShockerCommandListBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateShockerCommandList( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::Vector> commands = 0) { + ShockerCommandListBuilder builder_(_fbb); + builder_.add_commands(commands); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateShockerCommandListDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const std::vector *commands = nullptr) { + auto commands__ = commands ? _fbb.CreateVectorOfStructs(*commands) : 0; + return OpenShock::Serialization::CreateShockerCommandList( + _fbb, + commands__); +} + +struct ServerMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ServerMessageBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PAYLOAD_TYPE = 4, + VT_PAYLOAD = 6 + }; + OpenShock::Serialization::ServerMessagePayload payload_type() const { + return static_cast(GetField(VT_PAYLOAD_TYPE, 0)); + } + const void *payload() const { + return GetPointer(VT_PAYLOAD); + } + template const T *payload_as() const; + const OpenShock::Serialization::ShockerCommandList *payload_as_ShockerCommandList() const { + return payload_type() == OpenShock::Serialization::ServerMessagePayload_ShockerCommandList ? static_cast(payload()) : nullptr; + } + const OpenShock::Serialization::CaptivePortalConfig *payload_as_CaptivePortalConfig() const { + return payload_type() == OpenShock::Serialization::ServerMessagePayload_CaptivePortalConfig ? static_cast(payload()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_PAYLOAD_TYPE, 1) && + VerifyOffset(verifier, VT_PAYLOAD) && + VerifyServerMessagePayload(verifier, payload(), payload_type()) && + verifier.EndTable(); + } +}; + +template<> inline const OpenShock::Serialization::ShockerCommandList *ServerMessage::payload_as() const { + return payload_as_ShockerCommandList(); +} + +template<> inline const OpenShock::Serialization::CaptivePortalConfig *ServerMessage::payload_as() const { + return payload_as_CaptivePortalConfig(); +} + +struct ServerMessageBuilder { + typedef ServerMessage Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_payload_type(OpenShock::Serialization::ServerMessagePayload payload_type) { + fbb_.AddElement(ServerMessage::VT_PAYLOAD_TYPE, static_cast(payload_type), 0); + } + void add_payload(::flatbuffers::Offset payload) { + fbb_.AddOffset(ServerMessage::VT_PAYLOAD, payload); + } + explicit ServerMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateServerMessage( + ::flatbuffers::FlatBufferBuilder &_fbb, + OpenShock::Serialization::ServerMessagePayload payload_type = OpenShock::Serialization::ServerMessagePayload_NONE, + ::flatbuffers::Offset payload = 0) { + ServerMessageBuilder builder_(_fbb); + builder_.add_payload(payload); + builder_.add_payload_type(payload_type); + return builder_.Finish(); +} + +inline bool VerifyServerMessagePayload(::flatbuffers::Verifier &verifier, const void *obj, ServerMessagePayload type) { + switch (type) { + case ServerMessagePayload_NONE: { + return true; + } + case ServerMessagePayload_ShockerCommandList: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case ServerMessagePayload_CaptivePortalConfig: { + return verifier.VerifyField(static_cast(obj), 0, 1); + } + default: return true; + } +} + +inline bool VerifyServerMessagePayloadVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyServerMessagePayload( + verifier, values->Get(i), types->GetEnum(i))) { + return false; + } + } + return true; +} + +inline const OpenShock::Serialization::ServerMessage *GetServerMessage(const void *buf) { + return ::flatbuffers::GetRoot(buf); +} + +inline const OpenShock::Serialization::ServerMessage *GetSizePrefixedServerMessage(const void *buf) { + return ::flatbuffers::GetSizePrefixedRoot(buf); +} + +inline bool VerifyServerMessageBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer(nullptr); +} + +inline bool VerifySizePrefixedServerMessageBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer(nullptr); +} + +inline void FinishServerMessageBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.Finish(root); +} + +inline void FinishSizePrefixedServerMessageBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.FinishSizePrefixed(root); +} + +} // namespace Serialization +} // namespace OpenShock + +#endif // FLATBUFFERS_GENERATED_SERVERMESSAGES_OPENSHOCK_SERIALIZATION_H_ diff --git a/platformio.ini b/platformio.ini index 167b4ccc..e0c673b0 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,6 +18,7 @@ build_unflags = -std=gnu++11 lib_deps = bblanchon/ArduinoJson@^6.21.3 + https://github.com/OpenShock/flatbuffers https://github.com/martinmoene/span-lite https://github.com/me-no-dev/ESPAsyncWebServer https://github.com/Links2004/arduinoWebSockets diff --git a/schemas/ServerMessages.fbs b/schemas/ServerMessages.fbs new file mode 100644 index 00000000..7fa41599 --- /dev/null +++ b/schemas/ServerMessages.fbs @@ -0,0 +1,35 @@ +namespace OpenShock.Serialization; + +enum ShockerCommandType : uint8 { + Stop = 0, + Shock = 1, + Vibrate = 2, + Sound = 3 +} + +struct ShockerCommand { + model:uint8; + id:uint16; + type:ShockerCommandType; + intensity:uint8; + duration:uint32; +} + +table ShockerCommandList { + commands:[ShockerCommand]; +} + +struct CaptivePortalConfig { + enabled:bool; +} + +union ServerMessagePayload { + ShockerCommandList, + CaptivePortalConfig +} + +table ServerMessage { + payload:ServerMessagePayload; +} + +root_type ServerMessage; diff --git a/src/CommandHandler.cpp b/src/CommandHandler.cpp index ca15c475..86ec709d 100644 --- a/src/CommandHandler.cpp +++ b/src/CommandHandler.cpp @@ -27,18 +27,17 @@ void CommandHandler::Init() { #endif } -bool CommandHandler::HandleCommand(std::uint16_t shockerId, std::uint8_t method, std::uint8_t intensity, unsigned int duration, std::uint8_t shockerModel) { +bool CommandHandler::HandleCommand(std::uint16_t shockerId, ShockerCommandType type, std::uint8_t intensity, unsigned int duration, std::uint8_t shockerModel) { if (s_rfTransmitter == nullptr) return false; // Stop logic - bool isStop = method == 0; - if (isStop) { - method = 2; // Vibrate + if (type == ShockerCommandType::Stop) { + type = ShockerCommandType::Vibrate; intensity = 0; duration = 300; s_rfTransmitter->ClearPendingCommands(); } - return s_rfTransmitter->SendCommand(shockerModel, shockerId, method, intensity, duration); + return s_rfTransmitter->SendCommand(shockerModel, shockerId, type, intensity, duration); } diff --git a/src/GatewayConnectionManager.cpp b/src/GatewayConnectionManager.cpp index 65154edf..11217670 100644 --- a/src/GatewayConnectionManager.cpp +++ b/src/GatewayConnectionManager.cpp @@ -3,6 +3,7 @@ #include "CaptivePortal.h" #include "CommandHandler.h" #include "Constants.h" +#include "ShockerCommandType.h" #include "Time.h" #include "Utils/FileUtils.h" @@ -45,9 +46,10 @@ void _handleControlCommandMessage(const DynamicJsonDocument& doc) { std::uint8_t intensity = static_cast(cur["Intensity"]); unsigned int duration = static_cast(cur["Duration"]); std::uint8_t model = static_cast(cur["Model"]); - using namespace OpenShock; - if (!CommandHandler::HandleCommand(id, type, intensity, duration, model)) { + OpenShock::ShockerCommandType cmdType = static_cast(type); + + if (!OpenShock::CommandHandler::HandleCommand(id, cmdType, intensity, duration, model)) { ESP_LOGE(TAG, "Remote command failed/rejected!"); } } diff --git a/src/RFTransmitter.cpp b/src/RFTransmitter.cpp index 9bac7e4f..5a84eec3 100644 --- a/src/RFTransmitter.cpp +++ b/src/RFTransmitter.cpp @@ -58,7 +58,7 @@ RFTransmitter::~RFTransmitter() { bool RFTransmitter::SendCommand(std::uint8_t shockerModel, std::uint16_t shockerId, - std::uint8_t method, + ShockerCommandType type, std::uint8_t intensity, unsigned int duration) { if (!ok()) { @@ -71,7 +71,7 @@ bool RFTransmitter::SendCommand(std::uint8_t shockerModel, duration = std::min(duration, (unsigned int)std::numeric_limits::max()); command_t* cmd = new command_t {OpenShock::Millis() + duration, - Rmt::GetSequence(shockerId, method, intensity, shockerModel), + Rmt::GetSequence(shockerId, type, intensity, shockerModel), Rmt::GetZeroSequence(shockerId, shockerModel), shockerId}; diff --git a/src/Rmt/MainEncoder.cpp b/src/Rmt/MainEncoder.cpp index 4710a606..f75c6e17 100644 --- a/src/Rmt/MainEncoder.cpp +++ b/src/Rmt/MainEncoder.cpp @@ -12,12 +12,12 @@ const char* const TAG = "RmtMainEncoder"; using namespace OpenShock; std::vector - Rmt::GetSequence(std::uint16_t shockerId, std::uint8_t method, std::uint8_t intensity, std::uint8_t shockerModel) { + Rmt::GetSequence(std::uint16_t shockerId, ShockerCommandType type, std::uint8_t intensity, std::uint8_t shockerModel) { switch (shockerModel) { case 1: - return Rmt::PetTrainerEncoder::GetSequence(shockerId, method, intensity); + return Rmt::PetTrainerEncoder::GetSequence(shockerId, type, intensity); case 2: - return Rmt::XlcEncoder::GetSequence(shockerId, 0, method, intensity); + return Rmt::XlcEncoder::GetSequence(shockerId, 0, type, intensity); default: ESP_LOGE(TAG, "Unknown shocker model: %d", shockerModel); return {}; @@ -32,10 +32,12 @@ std::shared_ptr> Rmt::GetZeroSequence(std::uint16_t shoc std::shared_ptr> sequence; switch (shockerModel) { case 1: - sequence = std::make_shared>(Rmt::PetTrainerEncoder::GetSequence(shockerId, 2, 0)); + sequence = std::make_shared>( + Rmt::PetTrainerEncoder::GetSequence(shockerId, ShockerCommandType::Vibrate, 0)); break; case 2: - sequence = std::make_shared>(Rmt::XlcEncoder::GetSequence(shockerId, 0, 2, 0)); + sequence + = std::make_shared>(Rmt::XlcEncoder::GetSequence(shockerId, 0, ShockerCommandType::Vibrate, 0)); break; default: ESP_LOGE(TAG, "Unknown shocker model: %d", shockerModel); diff --git a/src/Rmt/PetTrainerEncoder.cpp b/src/Rmt/PetTrainerEncoder.cpp index e98b29af..ab54c261 100644 --- a/src/Rmt/PetTrainerEncoder.cpp +++ b/src/Rmt/PetTrainerEncoder.cpp @@ -5,16 +5,16 @@ const rmt_data_t kRmtOne = {200, 1, 1500, 0}; const rmt_data_t kRmtZero = {200, 1, 750, 0}; const rmt_data_t kRmtPostamble = {200, 1, 7000, 0}; +using namespace OpenShock; + std::vector - OpenShock::Rmt::PetTrainerEncoder::GetSequence(std::uint16_t shockerId, std::uint8_t method, std::uint8_t intensity) { - std::uint8_t methodBit = (0x80 | (1 << (method - 1))) & 0xFF; - std::uint8_t methodChecksum = 0xFF ^ ((1 << (8 - method)) | 1); + Rmt::PetTrainerEncoder::GetSequence(std::uint16_t shockerId, ShockerCommandType type, std::uint8_t intensity) { + std::uint8_t methodBit = (0x80 | (1 << ((std::uint8_t)type - 1))) & 0xFF; + std::uint8_t methodChecksum = 0xFF ^ ((1 << (8 - (std::uint8_t)type)) | 1); std::uint64_t data = (std::uint64_t(methodBit) << 32) | (std::uint64_t(shockerId) << 16) | (std::uint64_t(intensity) << 8) | (std::uint64_t(methodChecksum) << 0); - using namespace OpenShock; - std::vector pulses; pulses.reserve(42); diff --git a/src/Rmt/XlcEncoder.cpp b/src/Rmt/XlcEncoder.cpp index f7aba0db..cc5ebf83 100644 --- a/src/Rmt/XlcEncoder.cpp +++ b/src/Rmt/XlcEncoder.cpp @@ -10,13 +10,12 @@ using namespace OpenShock; std::vector Rmt::XlcEncoder::GetSequence(std::uint16_t transmitterId, std::uint8_t channelId, - std::uint8_t method, + ShockerCommandType type, std::uint8_t intensity) { std::uint64_t data = (std::uint64_t(transmitterId) << 24) | (std::uint64_t(channelId & 0xF) << 20) - | (std::uint64_t(method & 0xF) << 16) | (std::uint64_t(intensity & 0xFF) << 8); + | (std::uint64_t((std::uint8_t)type & 0xF) << 16) | (std::uint64_t(intensity & 0xFF) << 8); data |= Checksum::CRC8(data) & 0xFF; - using namespace OpenShock; data <<= 2; // The 2 last bits are always 0. this is the postamble of the packet.