mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-04-19 22:49:06 -04:00
Forced each message to have declared type as parts of Bus logic depends on it and previously we encountered undefined behaviours. Added tests and messages validators.
178 lines
4.9 KiB
C++
178 lines
4.9 KiB
C++
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#pragma once
|
|
|
|
#include <module-utils/magic_enum/include/magic_enum.hpp>
|
|
#include "Common.hpp"
|
|
#include "MessageType.hpp"
|
|
#include "MessageForward.hpp"
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
namespace sys
|
|
{
|
|
SendResult CreateSendResult(ReturnCodes retCode, MessagePointer msg);
|
|
|
|
inline constexpr std::uint64_t invalidMessageUid = std::numeric_limits<uint64_t>().max();
|
|
|
|
using MessageUIDType = std::uint64_t;
|
|
|
|
class MessageUID
|
|
{
|
|
protected:
|
|
MessageUIDType value = 0;
|
|
|
|
public:
|
|
[[nodiscard]] MessageUIDType get() const noexcept;
|
|
[[nodiscard]] MessageUIDType getNext() noexcept;
|
|
};
|
|
|
|
class Message
|
|
{
|
|
public:
|
|
enum class TransmissionType
|
|
{
|
|
Unspecified,
|
|
Unicast,
|
|
Multicast,
|
|
Broadcast
|
|
};
|
|
|
|
enum class Type
|
|
{
|
|
Unspecified,
|
|
System,
|
|
Data,
|
|
Response
|
|
};
|
|
|
|
explicit Message(Type type);
|
|
Message(Type type, BusChannel channel);
|
|
virtual ~Message() noexcept = default;
|
|
|
|
virtual MessagePointer Execute(Service *service);
|
|
|
|
virtual explicit operator std::string() const
|
|
{
|
|
return {"{}"};
|
|
}
|
|
|
|
MessageUIDType id = invalidMessageUid;
|
|
MessageUIDType uniID = invalidMessageUid;
|
|
Type type = Type::Unspecified;
|
|
TransmissionType transType = TransmissionType::Unspecified;
|
|
BusChannel channel = BusChannel::Unknown;
|
|
std::string sender = "Unknown";
|
|
|
|
[[nodiscard]] std::string to_string() const
|
|
{
|
|
return "| ID:" + std::to_string(id) + " | uniID: " + std::to_string(uniID) +
|
|
" | Type: " + std::string(magic_enum::enum_name(type)) +
|
|
" | TransmissionType: " + std::string(magic_enum::enum_name(transType)) +
|
|
" | Channel: " + std::string(magic_enum::enum_name(channel)) + " | Sender: " + sender + " |";
|
|
}
|
|
|
|
/**
|
|
* Validate base message have all essential fields set.
|
|
* @return Return validation result.
|
|
*/
|
|
[[nodiscard]] bool ValidateMessage() const noexcept;
|
|
|
|
/**
|
|
* Validate if response message have all essential fields set.
|
|
* @return Return validation result.
|
|
*/
|
|
void ValidateResponseMessage() const;
|
|
|
|
/**
|
|
* Validate if message sent via Unicast have all essential fields set.
|
|
* @return Return validation result.
|
|
*/
|
|
void ValidateUnicastMessage() const;
|
|
|
|
/**
|
|
* Validate if message sent via Broadcast have all essential fields set.
|
|
* @return Return validation result.
|
|
*/
|
|
void ValidateBroadcastMessage() const;
|
|
|
|
/**
|
|
* Validate if message sent via Multicast have all essential fields set.
|
|
* @return Return validation result.
|
|
*/
|
|
void ValidateMulticastMessage() const;
|
|
};
|
|
|
|
enum class SystemMessageType
|
|
{
|
|
Ping,
|
|
SwitchPowerMode,
|
|
Start,
|
|
Timer,
|
|
Exit,
|
|
ServiceCloseReason
|
|
};
|
|
|
|
class SystemMessage : public Message
|
|
{
|
|
public:
|
|
explicit SystemMessage(SystemMessageType systemMessageType,
|
|
ServicePowerMode pwrMode = ServicePowerMode::Active);
|
|
|
|
MessagePointer Execute(Service *service) final;
|
|
|
|
SystemMessageType systemMessageType;
|
|
ServicePowerMode powerMode;
|
|
};
|
|
|
|
class ServiceCloseReasonMessage : public SystemMessage
|
|
{
|
|
public:
|
|
explicit ServiceCloseReasonMessage(CloseReason closeReason);
|
|
|
|
[[nodiscard]] CloseReason getCloseReason() const noexcept;
|
|
|
|
private:
|
|
const CloseReason closeReason;
|
|
};
|
|
|
|
class DataMessage : public Message
|
|
{
|
|
public:
|
|
explicit DataMessage(MessageType messageType);
|
|
explicit DataMessage(BusChannel channel);
|
|
DataMessage();
|
|
|
|
// This field must by provided by the class that inherits DataMessage
|
|
MessageType messageType = MessageType::MessageTypeUninitialized;
|
|
};
|
|
|
|
class ReadyToCloseMessage : public DataMessage
|
|
{};
|
|
|
|
class ResponseMessage : public Message
|
|
{
|
|
public:
|
|
explicit ResponseMessage(ReturnCodes retCode = ReturnCodes::Success,
|
|
MessageType responseTo = MessageType::MessageTypeUninitialized);
|
|
|
|
MessagePointer Execute(Service *service) final;
|
|
|
|
ReturnCodes retCode;
|
|
MessageType responseTo;
|
|
};
|
|
|
|
inline auto msgHandled() -> MessagePointer
|
|
{
|
|
return std::make_shared<ResponseMessage>();
|
|
}
|
|
|
|
inline auto msgNotHandled() -> MessagePointer
|
|
{
|
|
return std::make_shared<ResponseMessage>(ReturnCodes::Unresolved);
|
|
}
|
|
} // namespace sys
|