mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 10:59:20 +02:00
Three additions, all driven from the simulator debug panel. DEVICE_LOG lets a controller send text lines; they reach the simulator log and a per connection view in the panel which keeps the last 64 of them. Diagnostic routines: a controller lists the procedures it offers, the operator picks one from a drop down and starts it, and the controller reports progress and the result. While a routine runs the controller can ask the simulator to show a message box with its own text and buttons and gets back which one was pressed, which is what a valve or gauge calibration needs. The message box appears whether the debug panel is open or not. Links can now be disconnected and reconnected by hand: disconnecting closes the serial port so the controller can be reprogrammed, and the session is rebuilt from scratch on reconnect. Ports which appear while the simulation runs can be picked from a refreshed list, given a baud rate and added as a new controller, so the manager now starts even with no uart2 entries in eu07.ini.
261 lines
5.6 KiB
C++
261 lines
5.6 KiB
C++
/*
|
|
This Source Code Form is subject to the
|
|
terms of the Mozilla Public License, v.
|
|
2.0. If a copy of the MPL was not
|
|
distributed with this file, You can
|
|
obtain one at
|
|
http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
|
|
// MaSzyna Hardware Protocol v2 (MHPv2)
|
|
// transport-independent protocol definitions shared by every transport (serial, TCP, RS-485)
|
|
|
|
namespace hardware
|
|
{
|
|
|
|
// protocol version implemented by this build
|
|
constexpr std::uint8_t protocol_version_major = 2;
|
|
constexpr std::uint8_t protocol_version_minor = 1;
|
|
|
|
// 'M2', stored little-endian in the frame header
|
|
constexpr std::uint16_t protocol_magic = 0x324D;
|
|
|
|
constexpr std::size_t protocol_header_size = 24;
|
|
constexpr std::size_t protocol_crc_size = 4;
|
|
|
|
constexpr std::size_t protocol_frame_size_min = 64;
|
|
constexpr std::size_t protocol_frame_size_default = 1024;
|
|
constexpr std::size_t protocol_frame_size_max = 4096;
|
|
|
|
// safety limits applied to anything arriving from the outside world
|
|
constexpr std::size_t protocol_symbol_name_max = 128;
|
|
constexpr std::size_t protocol_string_max = 128;
|
|
constexpr std::size_t protocol_symbols_per_message_max = 64;
|
|
constexpr std::size_t protocol_diagnostic_functions_max = 32;
|
|
constexpr std::size_t protocol_prompt_options_max = 4;
|
|
// device log lines kept per connection for the debug panel
|
|
constexpr std::size_t protocol_log_history = 64;
|
|
|
|
// message identifiers; the numbering is part of the public protocol and must not be reordered
|
|
enum class message_type : std::uint16_t
|
|
{
|
|
invalid = 0x0000,
|
|
|
|
hello = 0x0001,
|
|
welcome = 0x0002,
|
|
heartbeat = 0x0003,
|
|
|
|
ack = 0x0004,
|
|
nack = 0x0005,
|
|
|
|
ping = 0x0006,
|
|
pong = 0x0007,
|
|
|
|
device_ready = 0x0008,
|
|
|
|
device_info = 0x0010,
|
|
device_diagnostics = 0x0011,
|
|
device_log = 0x0012,
|
|
|
|
resolve_symbols = 0x0020,
|
|
symbols_resolved = 0x0021,
|
|
query_symbol = 0x0022,
|
|
symbol_info = 0x0023,
|
|
symbol_context_changed = 0x0024,
|
|
|
|
subscribe = 0x0030,
|
|
subscribe_result = 0x0031,
|
|
unsubscribe = 0x0032,
|
|
state_update = 0x0033,
|
|
|
|
command_event = 0x0040,
|
|
control_set = 0x0041,
|
|
|
|
control_claim = 0x0042,
|
|
control_claim_result = 0x0043,
|
|
control_release = 0x0044,
|
|
|
|
property_read = 0x0050,
|
|
property_value = 0x0051,
|
|
property_write = 0x0052,
|
|
|
|
diagnostic_functions = 0x0060,
|
|
diagnostic_run = 0x0061,
|
|
diagnostic_cancel = 0x0062,
|
|
diagnostic_status = 0x0063,
|
|
diagnostic_prompt = 0x0064,
|
|
diagnostic_prompt_result = 0x0065
|
|
};
|
|
|
|
// header flag bits
|
|
enum packet_flag : std::uint8_t
|
|
{
|
|
packetflag_none = 0x00,
|
|
packetflag_ack_required = 0x01,
|
|
packetflag_response = 0x02,
|
|
packetflag_error = 0x04,
|
|
packetflag_high_priority = 0x08,
|
|
packetflag_snapshot = 0x10
|
|
};
|
|
|
|
// wire data types
|
|
enum class value_type : std::uint8_t
|
|
{
|
|
none = 0x00,
|
|
boolean = 0x01,
|
|
uint8 = 0x02,
|
|
int8 = 0x03,
|
|
uint16 = 0x04,
|
|
int16 = 0x05,
|
|
uint32 = 0x06,
|
|
int32 = 0x07,
|
|
uint64 = 0x08,
|
|
int64 = 0x09,
|
|
float32 = 0x0A,
|
|
float64 = 0x0B,
|
|
utf8_string = 0x0C,
|
|
byte_array = 0x0D,
|
|
enumeration = 0x0E,
|
|
bitfield = 0x0F
|
|
};
|
|
|
|
// per-value quality indicator, so a device can tell "zero" from "not measured"
|
|
enum class value_quality : std::uint8_t
|
|
{
|
|
valid = 0,
|
|
stale = 1,
|
|
unavailable = 2,
|
|
invalid = 3,
|
|
not_applicable = 4
|
|
};
|
|
|
|
enum class symbol_kind : std::uint8_t
|
|
{
|
|
state = 0,
|
|
command = 1,
|
|
property = 2,
|
|
diagnostic = 3
|
|
};
|
|
|
|
enum access_mode : std::uint8_t
|
|
{
|
|
access_read = 0x01,
|
|
access_write = 0x02,
|
|
access_readwrite = 0x03
|
|
};
|
|
|
|
enum class subscription_mode : std::uint8_t
|
|
{
|
|
periodic = 0,
|
|
on_change = 1,
|
|
periodic_or_change = 2
|
|
};
|
|
|
|
enum class command_action : std::uint8_t
|
|
{
|
|
press = 0,
|
|
release = 1,
|
|
repeat = 2
|
|
};
|
|
|
|
enum class error_code : std::uint16_t
|
|
{
|
|
none = 0,
|
|
|
|
unsupported_version = 1,
|
|
invalid_session = 2,
|
|
|
|
invalid_frame = 3,
|
|
invalid_length = 4,
|
|
invalid_field = 5,
|
|
|
|
unknown_message = 6,
|
|
unknown_symbol = 7,
|
|
unknown_handle = 8,
|
|
|
|
access_denied = 9,
|
|
out_of_range = 10,
|
|
wrong_type = 11,
|
|
|
|
not_ready = 12,
|
|
busy = 13,
|
|
control_not_owned = 14,
|
|
|
|
rate_limited = 15,
|
|
|
|
unsupported_operation = 16,
|
|
internal_error = 17
|
|
};
|
|
|
|
// capabilities advertised by the device in HELLO
|
|
enum capability_flag : std::uint32_t
|
|
{
|
|
capability_none = 0x00000000,
|
|
capability_receive_state = 0x00000001,
|
|
capability_send_commands = 0x00000002,
|
|
capability_send_controls = 0x00000004,
|
|
capability_diagnostics = 0x00000008,
|
|
capability_soft_takeover = 0x00000010,
|
|
capability_control_leases = 0x00000020,
|
|
// the device offers diagnostic routines which can be started from the debug panel
|
|
capability_diagnostic_functions = 0x00000040
|
|
};
|
|
|
|
// severity of a text line sent by the device
|
|
enum class log_severity : std::uint8_t
|
|
{
|
|
debug = 0,
|
|
info = 1,
|
|
warning = 2,
|
|
error = 3
|
|
};
|
|
|
|
// progress of a diagnostic routine running on the device
|
|
enum class diagnostic_state : std::uint8_t
|
|
{
|
|
idle = 0,
|
|
running = 1,
|
|
succeeded = 2,
|
|
failed = 3
|
|
};
|
|
|
|
// answer index reported when the user closes a prompt without choosing
|
|
constexpr std::uint8_t prompt_dismissed = 0xFF;
|
|
|
|
// session progress, mirrors the connection lifecycle of the specification
|
|
enum class session_state : std::uint8_t
|
|
{
|
|
disconnected = 0,
|
|
waiting_for_hello = 1,
|
|
established = 2,
|
|
ready = 3
|
|
};
|
|
|
|
// aggregated link condition presented in the debug ui
|
|
enum class link_state : std::uint8_t
|
|
{
|
|
disconnected = 0,
|
|
connecting = 1,
|
|
healthy = 2,
|
|
degraded = 3,
|
|
error = 4
|
|
};
|
|
|
|
char const *to_string( message_type const Type );
|
|
char const *to_string( error_code const Code );
|
|
char const *to_string( value_quality const Quality );
|
|
char const *to_string( session_state const State );
|
|
char const *to_string( link_state const State );
|
|
char const *to_string( log_severity const Severity );
|
|
char const *to_string( diagnostic_state const State );
|
|
|
|
// size of a fixed-width type on the wire, 0 for variable-length ones
|
|
std::size_t value_type_size( value_type const Type );
|
|
|
|
} // namespace hardware
|