v1.3.0.0
WASimCommander.h
Go to the documentation of this file.
1/*
2This file is part of the WASimCommander project.
3https://github.com/mpaperno/WASimCommander
4
5COPYRIGHT: (c) Maxim Paperno; All Rights Reserved.
6
7This file may be used under the terms of either the GNU General Public License (GPL)
8or the GNU Lesser General Public License (LGPL), as published by the Free Software
9Foundation, either version 3 of the Licenses, or (at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16Copies of the GNU GPL and LGPL are included with this project
17and are available at <http://www.gnu.org/licenses/>.
18*/
19
20#pragma once
21#include <chrono>
22#include <cstdint>
23#include <iomanip>
24#include <ostream>
25
26#include "global.h"
27#include "wasim_version.h"
28#include "enums.h"
29
30/// \file
31
32//----------------------------------------------------------------------------
33// Macros
34//----------------------------------------------------------------------------
35
36// These macros are for building event and data area names for registration with SimConnect. They could be used for custom client implementations.
37#define WSMCMND_COMMON_NAME_PREFIX WSMCMND_PROJECT_NAME "." ///< common prefix for all event and data area names
38#define WSMCMND_EVENT_NAME_CONNECT "Connect" ///< Initial connection event for all clients: "WASimCommander.Connect"
39#define WSMCMND_EVENT_NAME_PING "Ping" ///< Ping event for all clients ("WASimCommander.Ping") and prefix for response event ("WASimCommander.Ping.<client_name>")
40#define WSMCMND_CDA_NAME_COMMAND "Command" ///< Data area name prefix for `Command` data sent to Server: "WASimCommander.Command.<client_name>"
41#define WSMCMND_CDA_NAME_RESPONSE "Response" ///< Data area name prefix for `Command` data sent to Client: "WASimCommander.Response.<client_name>"
42#define WSMCMND_CDA_NAME_DATA "Data" ///< Data area name prefix for `DataRequest` data sent to Server ("WASimCommander.Data.<client_name>") and data value updates sent to Client: "WASimCommander.Data.<client_name>.<request_id>"
43#define WSMCMND_CDA_NAME_KEYEVENT "KeyEvent" ///< Data area name prefix for `KeyEvent` data sent to Client: "WASimCommander.KeyEvent.<client_name>" \since v1.1.0
44#define WSMCMND_CDA_NAME_LOG "Log" ///< Data area name prefix for `LogRecord` data sent to Client: "WASimCommander.Log.<client_name>"
45
46/// WASimCommander main namespace. Defines constants and structs used in Client-Server interactions. Many of these are needed for effective use of `WASimClient`,
47/// and all would be useful for custom client implementations.
48namespace WASimCommander
49{
50//----------------------------------------------------------------------------
51// Constants
52//----------------------------------------------------------------------------
53
54 /// \name Char array string size limits, including null terminator.
55 /// \{
56 static const size_t STRSZ_CMD = 527; ///< Maximum size of \refwc{Command::sData} member. Size optimizes alignment of `Command` struct.
57 static const size_t STRSZ_REQ = 1030; ///< Maximum size for request calculator string or variable name. Size optimizes alignment of `DataRequest` struct. \sa \refwc{DataRequest::nameOrCode}
58 static const size_t STRSZ_UNIT = 37; ///< Maximum Unit name size. Size is of longest known unit name + 1. \sa \refwc{DataRequest::unitName}
59 static const size_t STRSZ_LOG = 1031; ///< Size of log entry message in \refwc{LogRecord::message}. Size optimizes alignment of `LogRecord` struct.
60 static const size_t STRSZ_ENAME = 64; ///< Maximum size of custom event name in \refwce{CommandId::Register} command.
61 /// \}
62
63 /// \name Time periods
64 /// \{
65 static const time_t TICK_PERIOD_MS = 25; ///< Minimum update period for data Requests in milliseconds. Also dictates rate of some other client-specific processing on server (WASM module) side. 25ms = 40Hz.
66 static const time_t CONN_TIMEOUT_SEC = 60 * 10; ///< Number of seconds after which a non-responsive client is considered disconnected. Client must respond to heartbeat pings from the server if not otherwise transmitting anything within this timeout period.
67 /// \}
68
69 /// \name Predefined value types
70 /// Using these constants for the \refwc{DataRequest::valueSize} property will allow delta epsilon comparisons.
71 /// \{
72 static const uint32_t DATA_TYPE_INT8 = -1; ///< 8-bit integer number (signed or unsigned)
73 static const uint32_t DATA_TYPE_INT16 = -2; ///< 16-bit integer number (signed or unsigned)
74 static const uint32_t DATA_TYPE_INT32 = -3; ///< 32-bit integer number (signed or unsigned)
75 static const uint32_t DATA_TYPE_INT64 = -4; ///< 64-bit integer number (signed or unsigned)
76 static const uint32_t DATA_TYPE_FLOAT = -5; ///< 32-bit floating-point number
77 static const uint32_t DATA_TYPE_DOUBLE = -6; ///< 64-bit floating-point number
78 /// \}
79
80//----------------------------------------------------------------------------
81// Struct definitions
82//----------------------------------------------------------------------------
83
84// Utility functions used by structs, not public API --------------------------
85 /// \private
86 static void setCharArrayValue(char *dest, const size_t size, const char *str) {
87 std::strncpy(dest, str, size-1);
88 dest[size-1] = '\0';
89 }
90 #define WSE WASimCommander::Enums
91//------------------------------------------------------------------
92
93 //using namespace WSE;
94
95 #pragma pack(push, 1)
96
97 /// Command data structure. The member contents depend on the command type as described in each command type of the `Enums::CommandId` enum documentation. \sa Enums::CommandId enum
98 struct WSMCMND_API Command
99 {
100 uint32_t token; ///< A unique ID for this command instance. Echoed back by server in command responses. Optional use for client implementations.
101 uint32_t uData; ///< DWORD command parameter value, meaning depends on the command being issued.
102 double fData; ///< double-precision floating point command parameter value, meaning depends on the command being issued.
103 WSE::CommandId commandId; ///< What to do. \sa CommandId
104 char sData[STRSZ_CMD] = {0}; ///< String command parameter value, meaning depends on the command being issued.
105 // 544/544 B (packed/unpacked), 8/16 B aligned
106
107 /// Default constructor with all parameters optional.
108 explicit Command(WSE::CommandId id = WSE::CommandId::None, uint32_t uData = 0, const char *str = nullptr, double fData = 0.0, int32_t token = 0) :
109 token(token), uData(uData), fData(fData), commandId(id)
110 {
111 if (str) setStringData(str);
112 }
113
114 void setStringData(const char *str) { setCharArrayValue(sData, STRSZ_CMD, str); } ///< Set the `sData` member using a const char array.
115
116 /// `ostream` operator for logging purposes
117 friend inline std::ostream& operator<<(std::ostream& os, const Command &c)
118 {
119 const char *cmdName = (size_t)c.commandId < WSE::CommandIdNames.size() ? WSE::CommandIdNames.at((size_t)c.commandId) : "Invalid";
120 return os << "Command{" << cmdName << "; token: " << c.token << "; uData: " << c.uData
121 << "; fData: " << std::fixed << std::setprecision(9) << c.fData << "; sData: " << std::quoted(c.sData) << '}';
122 }
123 };
124
125
126 /// Structure for variable value subscription requests. \sa WASimCommander:CommandId::Subscribe command.
127 struct WSMCMND_API DataRequest
128 {
129 uint32_t requestId; ///< Unique ID for the request, subsequent use of this ID overwrites any previous request definition (but size may not grow).
130 uint32_t valueSize; ///< Byte size of stored value; can also be one of the predefined DATA_TYPE_* constants. \sa WASimCommander::DATA_TYPE_INT8, etc
131 float deltaEpsilon; ///< Minimum change in numeric value required to trigger an update. The default of `0.0` is to send updates only if the value changes, but even on the smallest changes.
132 /// Setting this to some positive value can be especially useful for high-precision floating-point numbers which may fluctuate within an insignificant range,
133 /// but may be used with any numeric value (for integer value types, only the integer part of the epsilon value is considered).
134 /// Conversely, to send data updates _every time_ the value is read, and skip any comparison check altogether, set this to a negative value like `-1.0`.
135 ///< \note For the positive epsilon settings to work, the `valueSize` must be set to one of the predefined `DATA_TYPE_*` constants.
136 uint32_t interval; ///< How many `UpdatePeriod` period's should elapse between checks. eg. 500ms or 10 ticks.
137 /// Zero means to check at every `period`, `1` means every other `period`, etc.
138 WSE::UpdatePeriod period; ///< How often to read/calculate this value.
139 WSE::RequestType requestType; ///< Named variable or calculated value.
140 WSE::CalcResultType calcResultType; ///< Expected calculator result type.
141 uint8_t simVarIndex; ///< Some SimVars require an index for access, default is 0.
142 char varTypePrefix; ///< Variable type prefix for named variables. Types: 'L' (local), 'A' (SimVar) and 'T' (Token, not an actual GaugeAPI prefix) are checked using respective GaugeAPI methods.
143 char nameOrCode[STRSZ_REQ] = {0}; ///< Variable name or full calculator string.
144 char unitName[STRSZ_UNIT] = {0}; ///< Unit name for named variables (optional to override variable's default units). Only 'L' and 'A' variable types support unit specifiers.
145 // 1088/1088 B (packed/unpacked), 8/16 B aligned
146
147 /// Constructor with required request ID, all other parameters optional. See member documentation for explanation of the homonymous parameters.
148 explicit DataRequest(
149 uint32_t requestId,
150 uint32_t valueSize = sizeof(double),
151 WSE::RequestType requestType = WSE::RequestType::Calculated,
152 WSE::CalcResultType calcResultType = WSE::CalcResultType::Double,
153 WSE::UpdatePeriod period = WSE::UpdatePeriod::Tick,
154 const char * nameOrCode = nullptr,
155 const char * unitName = nullptr,
156 char varTypePrefix = 'L',
157 float deltaEpsilon = 0.0f,
158 uint8_t interval = 0,
159 uint8_t simVarIndex = 0
160 ) :
161 requestId(requestId), valueSize(valueSize), deltaEpsilon(deltaEpsilon), interval(interval), period(period),
162 requestType(requestType), calcResultType(calcResultType), simVarIndex(simVarIndex), varTypePrefix(varTypePrefix)
163 {
164 if (nameOrCode)
165 setNameOrCode(nameOrCode);
166 if (unitName)
167 setUnitName(unitName);
168 if (!valueSize && requestType == WSE::RequestType::Calculated)
169 this->valueSize = (calcResultType == WSE::CalcResultType::Double ? DATA_TYPE_DOUBLE : calcResultType == WSE::CalcResultType::Integer ? DATA_TYPE_INT32 : 256);
170 }
171
172 /// Constructs a request for a named variable (`requestType = RequestType::Named`) with optional update period, interval, and epsilon values.
173 explicit DataRequest(uint32_t requestId, char variableType, const char *variableName, uint32_t valueSize,
174 WSE::UpdatePeriod period = WSE::UpdatePeriod::Tick, uint32_t interval = 0, float deltaEpsilon = 0.0f) :
175 DataRequest(requestId, valueSize, WSE::RequestType::Named, WSE::CalcResultType::None, period, variableName, nullptr, variableType, deltaEpsilon, interval)
176 { }
177 /// Constructs a request for a named Simulator Variable (`requestType = RequestType::Named` and `varTypePrefix = 'A'`) with optional update period, interval, and epsilon values.
178 explicit DataRequest(uint32_t requestId, const char *simVarName, const char *unitName, uint8_t simVarIndex, uint32_t valueSize,
179 WSE::UpdatePeriod period = WSE::UpdatePeriod::Tick, uint32_t interval = 0, float deltaEpsilon = 0.0f) :
180 DataRequest(requestId, valueSize, WSE::RequestType::Named, WSE::CalcResultType::None, period, simVarName, unitName, 'A', deltaEpsilon, interval, simVarIndex)
181 { }
182 /// Constructs a calculator code request (`requestType = RequestType::Calculated`) with optional update period, interval, and epsilon values.
183 explicit DataRequest(uint32_t requestId, WSE::CalcResultType resultType, const char *calculatorCode, uint32_t valueSize,
184 WSE::UpdatePeriod period = WSE::UpdatePeriod::Tick, uint32_t interval = 0, float deltaEpsilon = 0.0f) :
185 DataRequest(requestId, valueSize, WSE::RequestType::Calculated, resultType, period, calculatorCode, nullptr, 'Q', deltaEpsilon, interval)
186 { }
187 /// Constructs a calculator code request (`requestType = RequestType::Calculated`) with optional update period, interval, and epsilon values. \n
188 /// This overload, w/out a `valueSize` argument automatically determines the size based on the `resultType` argument:
189 /// - `CalcResultType::Double` = `WASimCommander::DATA_TYPE_DOUBLE`
190 /// - `CalcResultType::Integer` = `WASimCommander::DATA_TYPE_INT32`
191 /// - `CalcResultType::String` = 256
192 explicit DataRequest(uint32_t requestId, WSE::CalcResultType resultType, const char *calculatorCode,
193 WSE::UpdatePeriod period = WSE::UpdatePeriod::Tick, uint32_t interval = 0, float deltaEpsilon = 0.0f) :
194 DataRequest(requestId, 0, WSE::RequestType::Calculated, resultType, period, calculatorCode, nullptr, 'Q', deltaEpsilon, interval)
195 { }
196
197 void setNameOrCode(const char *name) { setCharArrayValue(nameOrCode, STRSZ_REQ, name); } ///< Set the `nameOrCode` member using a const char array.
198 void setUnitName(const char *name) { setCharArrayValue(unitName, STRSZ_UNIT, name); } ///< Set the `unitName` member using a const char array.
199
200 /// `ostream` operator for logging purposes
201 friend inline std::ostream& operator<<(std::ostream& os, const DataRequest &r)
202 {
203 const char *perName = (size_t)r.period < WSE::UpdatePeriodNames.size() ? WSE::UpdatePeriodNames.at((size_t)r.period) : "Invalid";
204 os << "DataRequest{" << r.requestId << "; size: " << r.valueSize << "; period: " << perName << "; interval: " << r.interval << "; deltaE: " << r.deltaEpsilon;
205 if (r.requestType == WSE::RequestType::None)
206 return os << "; type: None; }";
207 if (r.requestType == WSE::RequestType::Named)
208 return os << "; type: Named; name: " << std::quoted(r.nameOrCode) << "; unit: " << std::quoted(r.unitName) << "; varType: '" << r.varTypePrefix << "'; varIndex: " << r.simVarIndex << '}';
209 const char *typeName = (size_t)r.calcResultType < WSE::CalcResultTypeNames.size() ? WSE::CalcResultTypeNames.at((size_t)r.calcResultType) : "Invalid";
210 return os << "; type: Calculated; code: " << std::quoted(r.nameOrCode) << " resultType: " << typeName << '}';
211 }
212 };
213
214 /// Data structure for sending Key Events to the sim with up to 5 event values. Events are specified using numeric MSFS Event IDs (names can be resolved to IDs via `Lookup` command).
215 /// This supports the new functionality in MSFS SU10 with `trigger_key_event_EX1()` Gauge API function (similar to `SimConnect_TransmitClientEvent_EX1()`).
216 /// The server will respond with an Ack/Nak for a `SendKey` command, echoing the given `token`. For events with zero or one value, the `SendKey` command can be used instead.
217 /// \since v1.1.0 \sa Enums::CommandId::SendKey, Enums::CommandId::Lookup
218 struct WSMCMND_API KeyEvent
219 {
220 uint32_t eventId; ///< The event ID to trigger. Value is one of `KEY_*` macro values in MSFS/Legacy/gauges.h. Event names can be resolved to IDs via `Lookup` command.
221 uint32_t values[5] = {0}; ///< Up to 5 values to pass to the event handler. All are optional, defaults are zero.
222 uint32_t token; ///< A unique ID for this event trigger. Echoed back by server in command Ack/Nak responses. Optional use for client implementations.
223 uint32_t reserved; ///< Padding for alignment, unused.
224 // 32/32 B (packed/unpacked), 8/16 B aligned
225
226 /// Default constructor with all parameters optional. The `values` initializer list may contain up to 5 members (any additional are ignored).
227 explicit KeyEvent(uint32_t eventId = 0, std::initializer_list<uint32_t> values = {}, uint32_t token = 0) :
228 eventId(eventId), token(token)
229 {
230 short i = 0;
231 for (const uint32_t v : values) {
232 this->values[i++] = v;
233 if (i > 4)
234 break;
235 }
236 }
237
238 /// `ostream` operator for logging purposes
239 friend inline std::ostream& operator<<(std::ostream& os, const KeyEvent &c)
240 {
241 os << "KeyEvent{eventId: " << c.eventId << "; token: " << c.token << ';';
242 for (short i=0; i < 5; ++i)
243 os << " v" << i << ": " << c.values[i] << ';';
244 return os << '}';
245 }
246 };
247
248
249 /// Log record structure. \sa WASimCommander:CommandId::Log command.
250 struct WSMCMND_API LogRecord
251 {
252 time_t timestamp; ///< ms since epoch.
253 WSE::LogLevel level; ///< Message severity.
254 char message[STRSZ_LOG] = {0}; ///< The log message text.
255 // 1040/1040 B (packed/unpacked), 8/16 B aligned
256
257 /// Default constructor with all parameters optional.
258 explicit LogRecord(const WSE::LogLevel level = WSE::LogLevel::None, const char *msg = nullptr, const std::chrono::system_clock::time_point &tp = std::chrono::system_clock::now()) :
259 timestamp{std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count()}, level{level}
260 {
261 if (msg) setMessage(msg);
262 }
263
264 void setMessage(const char *msg) { setCharArrayValue(message, STRSZ_LOG, msg); } ///< Set the `message` member using a const char array.
265
266 /// `ostream` operator for logging purposes
267 friend inline std::ostream& operator<<(std::ostream& os, const LogRecord &l)
268 {
269 const time_t secs = l.timestamp / 1000;
270 const tm *tim = std::localtime(&secs);
271 const char *levelName = (size_t)l.level < WSE::LogLevelNames.size() ? WSE::LogLevelNames.at((size_t)l.level) : "Invalid";
272 if (tim)
273 return os << "LogRecord{" << levelName << std::put_time(tim, " [(%z) %y-%m-%d %H:%M:%S.") << (l.timestamp - time_t(secs * 1000)) << "] " << l.message << '}';
274 return os << "LogRecord{" << levelName << " [" << l.timestamp << "] " << l.message << '}';
275 }
276 };
277
278 #pragma pack(pop)
279
280 #undef WSE
281}; // namespace WASimCommander
WASimCommander main namespace. Defines constants and structs used in Client-Server interactions....
Definition: enums_impl.h:32
static const size_t STRSZ_ENAME
Maximum size of custom event name in Enums::CommandId::Register command.
static const size_t STRSZ_LOG
Size of log entry message in LogRecord::message. Size optimizes alignment of LogRecord struct.
static const uint32_t DATA_TYPE_INT32
32-bit integer number (signed or unsigned)
static const uint32_t DATA_TYPE_INT16
16-bit integer number (signed or unsigned)
static const size_t STRSZ_UNIT
Maximum Unit name size. Size is of longest known unit name + 1.
static const size_t STRSZ_REQ
Maximum size for request calculator string or variable name. Size optimizes alignment of DataRequest ...
static const uint32_t DATA_TYPE_FLOAT
32-bit floating-point number
static const time_t CONN_TIMEOUT_SEC
Number of seconds after which a non-responsive client is considered disconnected. Client must respond...
static const size_t STRSZ_CMD
Maximum size of Command::sData member. Size optimizes alignment of Command struct.
static const uint32_t DATA_TYPE_INT64
64-bit integer number (signed or unsigned)
static const time_t TICK_PERIOD_MS
Minimum update period for data Requests in milliseconds. Also dictates rate of some other client-spec...
static const uint32_t DATA_TYPE_INT8
8-bit integer number (signed or unsigned)
static const uint32_t DATA_TYPE_DOUBLE
64-bit floating-point number
Command data structure. The member contents depend on the command type as described in each command t...
Command(WASimCommander::Enums::CommandId id=WASimCommander::Enums::CommandId::None, uint32_t uData=0, const char *str=nullptr, double fData=0.0, int32_t token=0)
Default constructor with all parameters optional.
char sData[STRSZ_CMD]
String command parameter value, meaning depends on the command being issued.
WASimCommander::Enums::CommandId commandId
What to do.
void setStringData(const char *str)
Set the sData member using a const char array.
friend std::ostream & operator<<(std::ostream &os, const Command &c)
ostream operator for logging purposes
double fData
double-precision floating point command parameter value, meaning depends on the command being issued.
uint32_t token
A unique ID for this command instance. Echoed back by server in command responses....
uint32_t uData
DWORD command parameter value, meaning depends on the command being issued.
Structure for variable value subscription requests.
uint8_t simVarIndex
Some SimVars require an index for access, default is 0.
uint32_t requestId
Unique ID for the request, subsequent use of this ID overwrites any previous request definition (but ...
DataRequest(uint32_t requestId, const char *simVarName, const char *unitName, uint8_t simVarIndex, uint32_t valueSize, WASimCommander::Enums::UpdatePeriod period=WASimCommander::Enums::UpdatePeriod::Tick, uint32_t interval=0, float deltaEpsilon=0.0f)
Constructs a request for a named Simulator Variable (requestType = RequestType::Named and ‘varTypePre...
void setUnitName(const char *name)
Set the unitName member using a const char array.
char unitName[STRSZ_UNIT]
Unit name for named variables (optional to override variable's default units). Only 'L' and 'A' varia...
DataRequest(uint32_t requestId, WASimCommander::Enums::CalcResultType resultType, const char *calculatorCode, WASimCommander::Enums::UpdatePeriod period=WASimCommander::Enums::UpdatePeriod::Tick, uint32_t interval=0, float deltaEpsilon=0.0f)
Constructs a calculator code request (requestType = RequestType::Calculated) with optional update per...
WASimCommander::Enums::UpdatePeriod period
How often to read/calculate this value.
friend std::ostream & operator<<(std::ostream &os, const DataRequest &r)
ostream operator for logging purposes
WASimCommander::Enums::RequestType requestType
Named variable or calculated value.
DataRequest(uint32_t requestId, char variableType, const char *variableName, uint32_t valueSize, WASimCommander::Enums::UpdatePeriod period=WASimCommander::Enums::UpdatePeriod::Tick, uint32_t interval=0, float deltaEpsilon=0.0f)
Constructs a request for a named variable (requestType = RequestType::Named) with optional update per...
uint32_t valueSize
Byte size of stored value; can also be one of the predefined DATA_TYPE_* constants.
DataRequest(uint32_t requestId, WASimCommander::Enums::CalcResultType resultType, const char *calculatorCode, uint32_t valueSize, WASimCommander::Enums::UpdatePeriod period=WASimCommander::Enums::UpdatePeriod::Tick, uint32_t interval=0, float deltaEpsilon=0.0f)
Constructs a calculator code request (requestType = RequestType::Calculated) with optional update per...
float deltaEpsilon
Minimum change in numeric value required to trigger an update. The default of 0.0 is to send updates ...
char nameOrCode[STRSZ_REQ]
Variable name or full calculator string.
void setNameOrCode(const char *name)
Set the nameOrCode member using a const char array.
DataRequest(uint32_t requestId, uint32_t valueSize=sizeof(double), WASimCommander::Enums::RequestType requestType=WASimCommander::Enums::RequestType::Calculated, WASimCommander::Enums::CalcResultType calcResultType=WASimCommander::Enums::CalcResultType::Double, WASimCommander::Enums::UpdatePeriod period=WASimCommander::Enums::UpdatePeriod::Tick, const char *nameOrCode=nullptr, const char *unitName=nullptr, char varTypePrefix='L', float deltaEpsilon=0.0f, uint8_t interval=0, uint8_t simVarIndex=0)
Constructor with required request ID, all other parameters optional. See member documentation for exp...
uint32_t interval
How many UpdatePeriod period's should elapse between checks. eg. 500ms or 10 ticks....
char varTypePrefix
Variable type prefix for named variables. Types: 'L' (local), 'A' (SimVar) and 'T' (Token,...
WASimCommander::Enums::CalcResultType calcResultType
Expected calculator result type.
Data structure for sending Key Events to the sim with up to 5 event values. Events are specified usin...
uint32_t eventId
The event ID to trigger. Value is one of KEY_* macro values in MSFS/Legacy/gauges....
uint32_t token
A unique ID for this event trigger. Echoed back by server in command Ack/Nak responses....
uint32_t values[5]
Up to 5 values to pass to the event handler. All are optional, defaults are zero.
friend std::ostream & operator<<(std::ostream &os, const KeyEvent &c)
ostream operator for logging purposes
KeyEvent(uint32_t eventId=0, std::initializer_list< uint32_t > values={}, uint32_t token=0)
Default constructor with all parameters optional. The values initializer list may contain up to 5 mem...
uint32_t reserved
Padding for alignment, unused.
Log record structure.
void setMessage(const char *msg)
Set the message member using a const char array.
LogRecord(const WASimCommander::Enums::LogLevel level=WASimCommander::Enums::LogLevel::None, const char *msg=nullptr, const std::chrono::system_clock::time_point &tp=std::chrono::system_clock::now())
Default constructor with all parameters optional.
friend std::ostream & operator<<(std::ostream &os, const LogRecord &l)
ostream operator for logging purposes
time_t timestamp
ms since epoch.
WASimCommander::Enums::LogLevel level
Message severity.
char message[STRSZ_LOG]
The log message text.