- CPU: max speed, bus MHz, L1/L2/L3 cache (from sysfs), voltage, socket type; /proc/cpuinfo fallback for non-root - Memory sticks: DDR type, form factor, part number, rank, data width, theoretical bandwidth - GPU: new part type discovered via lspci + /sys/class/drm + nvidia-smi; shows VRAM and display outputs - discover-only tree updated to show all new fields Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
192 lines
8.9 KiB
C++
192 lines
8.9 KiB
C++
#pragma once
|
||
#include <sstream>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
// Network
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
constexpr uint16_t DEFAULT_PORT = 9876;
|
||
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
// Wire-format separators
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
// FS (field separator) – SOH 0x01 – splits top-level tokens in a command line
|
||
constexpr char FS = '\x01';
|
||
|
||
// LS (list separator) – used to encode lists inside a single field value
|
||
// e.g. ip_addresses field: "192.168.1.2/24\x02fe80::1/64"
|
||
constexpr char LS = '\x02';
|
||
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
// Wire format
|
||
//
|
||
// Client → Server (one line per request):
|
||
// COMMAND<FS>arg1<FS>arg2…<newline>
|
||
//
|
||
// Server → Client:
|
||
// OK<newline>
|
||
// <data-row-line><newline> ← 0 or more rows
|
||
// END<newline>
|
||
// – or –
|
||
// ERR <message><newline>
|
||
//
|
||
// Key-value part commands:
|
||
// ADD_PART <type><FS>server_id<FS><int><FS>key1<FS>val1<FS>key2<FS>val2…
|
||
// UPSERT_PART <type><FS>server_id<FS><int><FS>key1<FS>val1…
|
||
// (insert or update matching an existing part by serial/mac)
|
||
// EDIT_PART <part_id><FS>key1<FS>val1<FS>key2<FS>val2…
|
||
// REMOVE_PART <part_id>
|
||
// LIST_PARTS <server_id> [optional: <FS><type>]
|
||
// GET_PART <part_id>
|
||
//
|
||
// List field values are encoded as val1<LS>val2<LS>val3
|
||
// (empty string encodes an empty list)
|
||
//
|
||
// Null / absent optional fields are sent as the literal string "NULL"
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
// Server management
|
||
constexpr const char* CMD_ADD_SERVER = "ADD_SERVER";
|
||
constexpr const char* CMD_LIST_SERVERS = "LIST_SERVERS";
|
||
constexpr const char* CMD_EDIT_SERVER = "EDIT_SERVER";
|
||
constexpr const char* CMD_REMOVE_SERVER = "REMOVE_SERVER";
|
||
|
||
// Part type (label) management
|
||
constexpr const char* CMD_ADD_PART_TYPE = "ADD_PART_TYPE";
|
||
constexpr const char* CMD_LIST_PART_TYPES = "LIST_PART_TYPES";
|
||
constexpr const char* CMD_EDIT_PART_TYPE = "EDIT_PART_TYPE";
|
||
constexpr const char* CMD_REMOVE_PART_TYPE = "REMOVE_PART_TYPE";
|
||
|
||
// Typed part management
|
||
constexpr const char* CMD_ADD_PART = "ADD_PART";
|
||
constexpr const char* CMD_UPSERT_PART = "UPSERT_PART"; // for discovery
|
||
constexpr const char* CMD_EDIT_PART = "EDIT_PART";
|
||
constexpr const char* CMD_REMOVE_PART = "REMOVE_PART";
|
||
constexpr const char* CMD_LIST_PARTS = "LIST_PARTS";
|
||
constexpr const char* CMD_GET_PART = "GET_PART";
|
||
|
||
// Response sentinels
|
||
constexpr const char* RESP_OK = "OK";
|
||
constexpr const char* RESP_ERR = "ERR";
|
||
constexpr const char* RESP_END = "END";
|
||
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
// Field keys for each specialized part type
|
||
// (shared between client serializer and server deserializer)
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
// PartBase common keys
|
||
constexpr const char* K_SERIAL = "serial";
|
||
constexpr const char* K_LAST_UPDATED = "last_updated";
|
||
|
||
// Natural keys for deduplication when serial is absent
|
||
constexpr const char* K_LOCATOR = "locator"; // DIMM locator for memory
|
||
constexpr const char* K_SOCKET = "socket_designation"; // CPU socket label
|
||
constexpr const char* K_DEVICE_NAME = "device_name"; // block device name (sda, nvme0n1…)
|
||
|
||
// MemoryStick
|
||
constexpr const char* K_SPEED_MHZ = "speed_mhz";
|
||
constexpr const char* K_SIZE_MB = "size_mb";
|
||
constexpr const char* K_MANUFACTURER = "manufacturer";
|
||
constexpr const char* K_CHANNEL_CONFIG = "channel_config";
|
||
constexpr const char* K_OTHER_INFO = "other_info";
|
||
|
||
// MemorySlot
|
||
constexpr const char* K_ALLOWED_SPEED = "allowed_speed_mhz";
|
||
constexpr const char* K_ALLOWED_SIZE = "allowed_size_mb";
|
||
constexpr const char* K_INSTALLED_STICK = "installed_stick_id";
|
||
|
||
// CPU
|
||
constexpr const char* K_NAME = "name";
|
||
constexpr const char* K_SPEED_GHZ = "speed_ghz";
|
||
constexpr const char* K_CORES = "cores";
|
||
constexpr const char* K_THREADS = "threads";
|
||
|
||
// CPU extended
|
||
constexpr const char* K_MAX_SPEED_GHZ = "max_speed_ghz";
|
||
constexpr const char* K_BUS_MHZ = "bus_speed_mhz";
|
||
constexpr const char* K_CACHE_L1_KB = "cache_l1_kb";
|
||
constexpr const char* K_CACHE_L2_KB = "cache_l2_kb";
|
||
constexpr const char* K_CACHE_L3_KB = "cache_l3_kb";
|
||
constexpr const char* K_VOLTAGE_V = "voltage_v";
|
||
constexpr const char* K_SOCKET_TYPE = "socket_type";
|
||
|
||
// CPUSlot
|
||
constexpr const char* K_FORM_FACTOR = "form_factor";
|
||
constexpr const char* K_INSTALLED_CPU = "installed_cpu_id";
|
||
|
||
// Disk
|
||
constexpr const char* K_MODEL = "model";
|
||
constexpr const char* K_GENERATION = "generation";
|
||
constexpr const char* K_CONN_TYPE = "connection_type";
|
||
constexpr const char* K_CONN_SPEED = "connection_speed_mbps";
|
||
constexpr const char* K_DISK_SPEED = "disk_speed_mbps";
|
||
constexpr const char* K_DISK_SIZE = "disk_size_gb";
|
||
constexpr const char* K_DISK_TYPE = "disk_type";
|
||
constexpr const char* K_AGE_YEARS = "age_years";
|
||
constexpr const char* K_PARTITION_IDS = "partition_ids"; // LS-separated
|
||
constexpr const char* K_PARTITION_SIZES = "partition_sizes_gb"; // LS-separated
|
||
constexpr const char* K_VM_HOSTNAMES = "vm_hostnames"; // LS-separated
|
||
constexpr const char* K_VM_SERVER_IDS = "vm_server_ids"; // LS-separated
|
||
|
||
// NetworkCard
|
||
constexpr const char* K_AGE_YEARS_NIC = "age_years"; // same key, different struct
|
||
constexpr const char* K_SPEED_MBPS = "connection_speed_mbps";
|
||
constexpr const char* K_MAC = "mac_address";
|
||
constexpr const char* K_IPS = "ip_addresses"; // LS-separated
|
||
constexpr const char* K_DHCP = "dhcp";
|
||
|
||
// MemoryStick extended
|
||
constexpr const char* K_MEM_TYPE = "memory_type";
|
||
constexpr const char* K_PART_NUMBER = "part_number";
|
||
constexpr const char* K_RANK = "rank";
|
||
constexpr const char* K_DATA_WIDTH = "data_width_bits";
|
||
constexpr const char* K_BANDWIDTH_MBPS = "bandwidth_mbps";
|
||
|
||
// GPU
|
||
constexpr const char* K_VRAM_MB = "vram_mb";
|
||
constexpr const char* K_GPU_BANDWIDTH_MBPS = "gpu_bandwidth_mbps";
|
||
constexpr const char* K_DISPLAY_OUTPUTS = "display_outputs";
|
||
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
// Helpers
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
inline std::vector<std::string> split(const std::string& s, char delim) {
|
||
std::vector<std::string> parts;
|
||
std::stringstream ss(s);
|
||
std::string token;
|
||
while (std::getline(ss, token, delim))
|
||
parts.push_back(token);
|
||
return parts;
|
||
}
|
||
|
||
inline std::string join(const std::vector<std::string>& v, char delim) {
|
||
std::string out;
|
||
for (size_t i = 0; i < v.size(); ++i) {
|
||
if (i) out += delim;
|
||
out += v[i];
|
||
}
|
||
return out;
|
||
}
|
||
|
||
inline std::string join_u64(const std::vector<uint64_t>& v, char delim) {
|
||
std::string out;
|
||
for (size_t i = 0; i < v.size(); ++i) {
|
||
if (i) out += delim;
|
||
out += std::to_string(v[i]);
|
||
}
|
||
return out;
|
||
}
|
||
|
||
inline std::string join_u32(const std::vector<uint32_t>& v, char delim) {
|
||
std::string out;
|
||
for (size_t i = 0; i < v.size(); ++i) {
|
||
if (i) out += delim;
|
||
out += std::to_string(v[i]);
|
||
}
|
||
return out;
|
||
}
|