Motion Master 6.0.0-alpha.50
Next-generation motion control software
Loading...
Searching...
No Matches
mm Namespace Reference

Namespaces

namespace  api
 HTTP-transport glue shared by the built-in server and route plug-in libs.
 
namespace  comm
 
namespace  core
 
namespace  example
 Example application namespace — the starting point for a C++ HTTP-endpoint plug-in.
 
namespace  node
 

Classes

struct  CertChainLink
 One certificate in the served chain — its subject/issuer common names plus the issuing organization (the friendly CA name, e.g. "Let's Encrypt", which lives in the O field rather than the CN). More...
 
struct  CertInfo
 Validity window and identity of a TLS leaf certificate, plus the full served chain. More...
 
struct  ResolvedCert
 The TLS cert/key paths the server should use, plus where they came from. More...
 
class  RingLogSink
 Thread-safe spdlog sink that retains the most recent log entries in memory. More...
 
struct  WsCommand
 A client request received over the monitoring WebSocket to (un)subscribe to a topic. More...
 

Typedefs

using RingLogSinkMt = RingLogSink< std::mutex >
 Convenience alias: RingLogSink with a std::mutex (multi-threaded).
 

Functions

std::expected< CertInfo, std::string > readCertInfo (const std::string &certPath)
 Parses a PEM file and extracts the leaf's validity window and the full certificate chain.
 
std::expected< void, std::string > fetchAndSwapCert (const std::string &certPath, const std::string &keyPath, const std::string &certUrl, const std::string &keyUrl)
 Downloads a fresh certificate and key and atomically installs them.
 
ResolvedCert resolveCertPaths (const std::string &configCertPath, const std::string &configKeyPath, const std::filesystem::path &defaultCertPath, const std::filesystem::path &defaultKeyPath)
 Resolve the TLS cert/key file paths, choosing by discovery when not configured.
 
std::expected< void, std::string > healCertIfNeeded (const std::string &certPath, const std::string &keyPath, bool autoUpdate, const std::string &certUrl, const std::string &keyUrl)
 Assess the served TLS certificate and refresh it if missing, expired, or expiring soon (the startup "cert self-heal").
 
std::string defaultCertUrl ()
 Default rolling-release URL for the current TLS certificate.
 
std::string defaultKeyUrl ()
 Default rolling-release URL for the current TLS private key. See defaultCertUrl.
 
std::optional< WsCommandparseWsCommand (std::string_view message)
 Parses an inbound monitoring-WebSocket text message into a subscribe/unsubscribe command.
 
std::expected< mm::node::Monitoring, std::string > parseMonitoringRequest (const nlohmann::json &body)
 Parses a POST /api/monitorings request body into a Monitoring config.
 

Variables

constexpr int kCertExpiringSoonDays = 7
 Number of days before notAfter at which a certificate is considered "expiring soon". A cert inside this window is refreshed proactively: it is one of the conditions that trigger the startup self-heal fetch (healCertIfNeeded), so a cert is renewed before it lapses rather than after. Also logs a startup warning and sets the expiresSoon flag returned by GET /api/cert.
 

Typedef Documentation

◆ RingLogSinkMt

using mm::RingLogSinkMt = typedef RingLogSink<std::mutex>

Convenience alias: RingLogSink with a std::mutex (multi-threaded).

Function Documentation

◆ defaultCertUrl()

std::string mm::defaultCertUrl ( )
inline

Default rolling-release URL for the current TLS certificate.

Published monthly by .github/workflows/cert-renewal.yml to a fixed-tag release, so this URL always serves the freshest cert regardless of when the application was last released.

◆ defaultKeyUrl()

std::string mm::defaultKeyUrl ( )
inline

Default rolling-release URL for the current TLS private key. See defaultCertUrl.

◆ fetchAndSwapCert()

std::expected< void, std::string > mm::fetchAndSwapCert ( const std::string &  certPath,
const std::string &  keyPath,
const std::string &  certUrl,
const std::string &  keyUrl 
)

Downloads a fresh certificate and key and atomically installs them.

Fetches certUrl and keyUrl over HTTPS (following redirects), then validates the downloaded pair before touching the live files:

  • the certificate parses as PEM and its subject CN is local.motion-master.synapticon.com,
  • the certificate is not already expired,
  • the private key parses and matches the certificate. Only if all checks pass are certPath and keyPath atomically replaced (write-to-temp in the same directory, then rename); the key is written with 0600 permissions. On any failure the existing files are left untouched.
Parameters
certPathDestination path for the certificate (overwritten on success).
keyPathDestination path for the private key (overwritten on success).
certUrlSource URL for the certificate.
keyUrlSource URL for the private key.
Returns
Empty on success, or an error string describing the first failure.

◆ healCertIfNeeded()

std::expected< void, std::string > mm::healCertIfNeeded ( const std::string &  certPath,
const std::string &  keyPath,
bool  autoUpdate,
const std::string &  certUrl,
const std::string &  keyUrl 
)

Assess the served TLS certificate and refresh it if missing, expired, or expiring soon (the startup "cert self-heal").

Inspects certPath: a missing cert, an expired one, or one expiring within kCertExpiringSoonDays triggers a fetch from certUrl / keyUrl via fetchAndSwapCert; a cert with ample life left is left alone, so a healthy boot makes no network call. Refreshing on imminent expiry — not just after it lapses — lets an ephemeral container (and the Docker entrypoint's 1-day self-signed fallback, which reads as expiring soon) self-heal to a fresh cert on start. The outcome is logged. When autoUpdate is false no fetch is attempted.

The fatal case is "no certificate that can be served": the cert is missing and either fetching is disabled or the fetch failed. A present cert (expired or expiring) is a degraded success — it still binds TLS, so it is served rather than failing when the fetch cannot run or fails.

Parameters
certPathPath to the served certificate (overwritten on a successful fetch).
keyPathPath to the served private key (overwritten on a successful fetch).
autoUpdateWhether a missing/expired/expiring cert may be fetched.
certUrlSource URL for the certificate fetch.
keyUrlSource URL for the private-key fetch.
Returns
Empty on success (including the present-but-served degraded case), or an error string when TLS cannot be served at all.

◆ parseMonitoringRequest()

std::expected< mm::node::Monitoring, std::string > mm::parseMonitoringRequest ( const nlohmann::json &  body)

Parses a POST /api/monitorings request body into a Monitoring config.

Expected shape:

{ "topic": "left-leg", "name": "Left Leg" (optional),
"interval": 1000,
"parameters": [[devicePosition, index, subindex], ...] }

interval is the flush cadence in milliseconds. Each parameter is a three-element array of integers. This checks only the request shape (presence, JSON types, ranges) and converts it; semantic validation (URL-safe/reserved topic, interval bounds, parameter sourcing) is MonitoringManager::create's job. (A legacy bufferSize key, if present, is ignored.)

Parameters
bodyThe parsed request body.
Returns
The configuration, or an error string naming the first shape problem.

◆ parseWsCommand()

std::optional< WsCommand > mm::parseWsCommand ( std::string_view  message)

Parses an inbound monitoring-WebSocket text message into a subscribe/unsubscribe command.

Accepts exactly {"subscribe":"<topic>"} or {"unsubscribe":"<topic>"} where <topic> is a URL-safe id. Anything else — malformed JSON, a non-object, an unknown key, a non-string or non-URL-safe topic — yields nullopt so the caller can simply ignore it. Pure (no I/O), so it is unit-tested directly; the server's message handler calls it and then ws->subscribe / ws->unsubscribe.

Parameters
messageThe raw WebSocket text frame.
Returns
The parsed command, or nullopt if message is not a valid (un)subscribe request.

◆ readCertInfo()

std::expected< CertInfo, std::string > mm::readCertInfo ( const std::string &  certPath)

Parses a PEM file and extracts the leaf's validity window and the full certificate chain.

The leaf-level subject / issuer / notBefore / notAfter come from the first certificate in the file; chain contains every certificate present, leaf first.

Parameters
certPathFilesystem path to a PEM-encoded certificate (leaf or fullchain).
Returns
The parsed CertInfo, or an error string if the file cannot be opened or parsed.

◆ resolveCertPaths()

ResolvedCert mm::resolveCertPaths ( const std::string &  configCertPath,
const std::string &  configKeyPath,
const std::filesystem::path &  defaultCertPath,
const std::filesystem::path &  defaultKeyPath 
)

Resolve the TLS cert/key file paths, choosing by discovery when not configured.

If configCertPath and configKeyPath are both set (e.g. from the config file) they are used as-is. Otherwise both are chosen from the first available source:

  1. defaultCertPath / defaultKeyPath next to the binary (a release install),
  2. ~/.acme.sh/local.motion-master.synapticon.com_ecc/ (a local acme.sh install),
  3. failing both, defaultCertPath / defaultKeyPath unconditionally — so the result is always populated and the caller's self-heal can fetch into it.
Parameters
configCertPathCertificate path from configuration; empty if unset.
configKeyPathPrivate-key path from configuration; empty if unset.
defaultCertPathInstall-dir certificate path (next to the binary).
defaultKeyPathInstall-dir private-key path (next to the binary).
Returns
The resolved paths and the discovered source (empty source when not discovered).

Variable Documentation

◆ kCertExpiringSoonDays

constexpr int mm::kCertExpiringSoonDays = 7
inlineconstexpr

Number of days before notAfter at which a certificate is considered "expiring soon". A cert inside this window is refreshed proactively: it is one of the conditions that trigger the startup self-heal fetch (healCertIfNeeded), so a cert is renewed before it lapses rather than after. Also logs a startup warning and sets the expiresSoon flag returned by GET /api/cert.