// beyond_prox_ctl - Control tool for Beyond Proximity SteamVR driver // Sends commands to the driver via named pipe and prints response. // // Usage: // beyond_prox_ctl "proximity on" -- Set proximity to true (HMD in use) // beyond_prox_ctl "proximity off" -- Set proximity to false (HMD idle) // beyond_prox_ctl "status" -- Query current driver state // beyond_prox_ctl "ipd 63.5" -- Set IPD to 63.5mm // beyond_prox_ctl "ipd?" -- Query current IPD // beyond_prox_ctl "backglow fill FF0000" -- Set all 10 LEDs red // beyond_prox_ctl "backglow set 3 00FF00" -- Light only LED 3 green // beyond_prox_ctl "backglow bri 100" -- Set master brightness // beyond_prox_ctl "backglow off" -- Turn LEDs off // beyond_prox_ctl "backglow on" -- Turn LEDs on // // Pipe: \\.\pipe\beyond_proximity_ctl #include #include #include static const char* PIPE_NAME = "\\\\.\\pipe\\beyond_proximity_ctl"; static void PrintUsage(const char* argv0) { fprintf(stderr, "Usage: %s \n", argv0); fprintf(stderr, "\nCommands:\n"); fprintf(stderr, " \"proximity on\" Set proximity to true (person detected)\n"); fprintf(stderr, " \"proximity off\" Set proximity to false (no person)\n"); fprintf(stderr, " \"proximity auto\" Clear manual override, let algorithm drive\n"); fprintf(stderr, " \"status\" Query driver state (proximity, HID, IPD, config)\n"); fprintf(stderr, " \"ipd \" Set IPD in millimeters (48-75mm range)\n"); fprintf(stderr, " \"ipd?\" Query current IPD value\n"); fprintf(stderr, " \"load_lh_config \" Load lighthouse config from explicit file path\n"); fprintf(stderr, " \"backglow fill \" Set all 10 LEDs (e.g. backglow fill FF8000)\n"); fprintf(stderr, " \"backglow fill ... \" Set per-LED colors (10 hex values)\n"); fprintf(stderr, " \"backglow set \" Set single LED (idx 0..9, hex RRGGBB)\n"); fprintf(stderr, " \"backglow bri <0..255>\" Set master brightness (clamped by ceiling)\n"); fprintf(stderr, " \"backglow off\" Turn LEDs off\n"); fprintf(stderr, " \"backglow on\" Turn LEDs on\n"); fprintf(stderr, " \"backglow status\" Show transport/conn/port|host/bri/ceiling/leds (multi-line)\n"); } int main(int argc, char* argv[]) { if (argc < 2) { PrintUsage(argv[0]); return 1; } const char* command = argv[1]; // Validate known commands bool validCommand = strcmp(command, "proximity on") == 0 || strcmp(command, "proximity off") == 0 || strcmp(command, "proximity auto") == 0 || strcmp(command, "status") == 0 || strncmp(command, "ipd ", 4) == 0 || strcmp(command, "ipd?") == 0 || strncmp(command, "load_lh_config ", 15) == 0 || strncmp(command, "backglow fill", 13) == 0 || strncmp(command, "backglow set ", 13) == 0 || strncmp(command, "backglow bri ", 13) == 0 || strcmp(command, "backglow off") == 0 || strcmp(command, "backglow on") == 0 || strcmp(command, "backglow status") == 0; // Phase 15 (D-19) if (!validCommand) { fprintf(stderr, "Error: Unknown command '%s'\n", command); PrintUsage(argv[0]); return 1; } // Connect to driver's named pipe HANDLE hPipe = CreateFileA( PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, // no sharing nullptr, // default security OPEN_EXISTING, 0, // default attributes nullptr); // no template if (hPipe == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err == ERROR_FILE_NOT_FOUND) fprintf(stderr, "Error: Driver pipe not found. Is the Beyond Proximity driver loaded in SteamVR?\n"); else fprintf(stderr, "Error: Cannot connect to driver pipe (error %lu)\n", err); return 1; } // Set pipe to message-read mode (must match server's PIPE_TYPE_MESSAGE). // WR-04 (Phase 15 review): surface failure so the user sees a diagnostic // instead of silently reading in byte-stream mode (which can truncate // multi-line responses like `backglow status`). Non-fatal — continue in // byte mode since short single-line responses still work. DWORD mode = PIPE_READMODE_MESSAGE; if (!SetNamedPipeHandleState(hPipe, &mode, nullptr, nullptr)) { fprintf(stderr, "Warning: Could not set pipe to message mode (error %lu); " "multi-line responses may be truncated\n", GetLastError()); // non-fatal — continue; byte-mode still works for short responses } // Send command DWORD written = 0; if (!WriteFile(hPipe, command, (DWORD)strlen(command), &written, nullptr)) { fprintf(stderr, "Error: Failed to send command (error %lu)\n", GetLastError()); CloseHandle(hPipe); return 1; } // Read response char response[1024] = {0}; // Phase 15: multi-line `backglow status` (~200 B nominal, 5x headroom) DWORD bytesRead = 0; if (ReadFile(hPipe, response, sizeof(response) - 1, &bytesRead, nullptr) && bytesRead > 0) { response[bytesRead] = '\0'; printf("%s\n", response); } else { fprintf(stderr, "Error: No response from driver (error %lu)\n", GetLastError()); CloseHandle(hPipe); return 1; } CloseHandle(hPipe); return 0; }