Private
Public Access
Release 0.12.0
This commit is contained in:
1 parent
f74a658097
commit
7f6eeab39e
48 files changed
+3617
-1266
No files matched your search
@@ -0,0 +1,202 @@
|
||||
/* Luna API handlers. Included after the shared runtime context. */
|
||||
#include "service_calibration.h"
|
||||
static bool start_failure(void *h, void *m, const char *message) {
|
||||
retry_update(&retries, boot_enabled() && geteuid() == 0, false, milliseconds());
|
||||
char json[512];
|
||||
snprintf(
|
||||
json, sizeof(json),
|
||||
"{\"returnValue\":false,\"errorText\":\"%s\",\"retryScheduled\":%s,\"retryBlocked\":%s}",
|
||||
message, retries.due ? "true" : "false", retries.blocked ? "true" : "false");
|
||||
return respond(h, m, json);
|
||||
}
|
||||
static bool start(void *h, void *m, void *ctx) {
|
||||
(void)ctx;
|
||||
const char *p = m ? payload(m) : NULL;
|
||||
if (p && strcmp(p, "{}") != 0)
|
||||
return respond(h, m,
|
||||
"{\"returnValue\":false,\"errorText\":\"Start expects an empty object; use "
|
||||
"settings to configure the receiver\"}");
|
||||
if (m)
|
||||
retry_reset(&retries);
|
||||
if (piccap_owned)
|
||||
return respond(h, m, "{\"returnValue\":true,\"running\":true,\"activeSource\":\"PicCap\"}");
|
||||
if (capture)
|
||||
return respond(h, m, "{\"returnValue\":true,\"running\":true}");
|
||||
frames = 0;
|
||||
revoked = 0;
|
||||
last_error[0] = 0;
|
||||
lg_diagnostic[0] = 0;
|
||||
output = target_connect(&target);
|
||||
if (output < 0) {
|
||||
stop_capture();
|
||||
set_error("Cannot connect to configured receiver IP and JSON port");
|
||||
return start_failure(h, m, "Configured receiver is unavailable");
|
||||
}
|
||||
if (!target_login()) {
|
||||
stop_capture();
|
||||
set_error("Receiver token login failed; check the saved API token");
|
||||
return start_failure(h, m, "Receiver authentication failed");
|
||||
}
|
||||
if (!read_layout()) {
|
||||
stop_capture();
|
||||
set_error("Cannot read receiver LED layout; check JSON port and API authorization");
|
||||
return start_failure(h, m, "Receiver layout unavailable; check API authorization");
|
||||
}
|
||||
if (!enter_developer_mode()) {
|
||||
stop_capture();
|
||||
set_error("Developer initialization needs root. Elevate this own service through Homebrew "
|
||||
"Channel.");
|
||||
return start_failure(h, m,
|
||||
"Root access is required for temporary LG developer initialization");
|
||||
}
|
||||
capture = vt_init(policy);
|
||||
if (!leave_developer_mode()) {
|
||||
stop_capture();
|
||||
retries.blocked = true;
|
||||
set_error("Developer marker cleanup failed; manual intervention required");
|
||||
return start_failure(h, m, "Developer marker cleanup failed");
|
||||
}
|
||||
if (!capture) {
|
||||
stop_capture();
|
||||
set_error("LG refused histogram initialization");
|
||||
return start_failure(
|
||||
h, m,
|
||||
"LG refused histogram initialization. Another capture source may hold VT_CAPTURE.");
|
||||
}
|
||||
if (vt_preset(capture, 0) != 0) {
|
||||
stop_capture();
|
||||
set_error("LG histogram preset initialization failed");
|
||||
return start_failure(h, m, "Histogram preset failed");
|
||||
}
|
||||
capture_preset = letterbox_mode = settling = 0;
|
||||
pending_letterbox = -1;
|
||||
next_border_probe = 0;
|
||||
retries.due = 0;
|
||||
retries.attempts = 0;
|
||||
retries.quick_retries = 0;
|
||||
if (recovery_started) {
|
||||
last_recovery_ms = milliseconds() - recovery_started;
|
||||
recovery_started = 0;
|
||||
}
|
||||
return respond(h, m, "{\"returnValue\":true,\"running\":true}");
|
||||
}
|
||||
static bool stop(void *h, void *m, void *ctx) {
|
||||
(void)ctx;
|
||||
calibration_until = 0;
|
||||
retry_pause(&retries);
|
||||
bool bridging = bridge_phase != BRIDGE_IDLE;
|
||||
stream_close(milliseconds());
|
||||
bridge_phase = BRIDGE_IDLE;
|
||||
memset(&continuity, 0, sizeof(continuity));
|
||||
stop_capture();
|
||||
if (bridging) {
|
||||
output = target_connect(&target);
|
||||
if (output >= 0) {
|
||||
if (target_login())
|
||||
send_line("{\"command\":\"clear\",\"priority\":149}\n");
|
||||
close(output);
|
||||
output = -1;
|
||||
}
|
||||
}
|
||||
return respond(h, m, "{\"returnValue\":true,\"running\":false}");
|
||||
}
|
||||
static bool autostart(void *h, void *m, void *ctx) {
|
||||
(void)ctx;
|
||||
const char *p = m ? payload(m) : NULL;
|
||||
bool enabled;
|
||||
if (p && strcmp(p, "{\"enabled\":true}") == 0)
|
||||
enabled = true;
|
||||
else if (p && strcmp(p, "{\"enabled\":false}") == 0)
|
||||
enabled = false;
|
||||
else
|
||||
return respond(h, m, "{\"returnValue\":false,\"errorText\":\"Expected enabled boolean\"}");
|
||||
if (geteuid() != 0)
|
||||
return respond(
|
||||
h, m,
|
||||
"{\"returnValue\":false,\"rootRequired\":true,\"errorText\":\"Root access is required "
|
||||
"to change autostart. Select Enable Root Access in Overview.\"}");
|
||||
if (!set_boot(enabled))
|
||||
return respond(
|
||||
h, m,
|
||||
"{\"returnValue\":false,\"errorText\":\"Cannot update the HyperDRM boot hook. Check "
|
||||
"the installed boot script and whether another file occupies the hook path.\"}");
|
||||
if (enabled)
|
||||
retry_reset(&retries);
|
||||
retry_update(&retries, enabled, capture != NULL, milliseconds());
|
||||
return respond(h, m,
|
||||
enabled ? "{\"returnValue\":true,\"autostart\":true}"
|
||||
: "{\"returnValue\":true,\"autostart\":false}");
|
||||
}
|
||||
static bool restart_service(void *h, void *m, void *ctx) {
|
||||
(void)ctx;
|
||||
if (strcmp(payload(m), "{}"))
|
||||
return respond(h, m,
|
||||
"{\"returnValue\":false,\"errorText\":\"Restart expects an empty object\"}");
|
||||
bool ok = respond(h, m, "{\"returnValue\":true,\"restarting\":true}");
|
||||
quitting = 1;
|
||||
return ok;
|
||||
}
|
||||
static bool handover(void *h, void *m, void *ctx) {
|
||||
(void)ctx;
|
||||
const char *p = payload(m);
|
||||
bool enabled;
|
||||
if (strcmp(p, "{\"enabled\":true}") == 0)
|
||||
enabled = true;
|
||||
else if (strcmp(p, "{\"enabled\":false}") == 0)
|
||||
enabled = false;
|
||||
else
|
||||
return respond(h, m, "{\"returnValue\":false,\"errorText\":\"Expected enabled boolean\"}");
|
||||
if (!playback_json.lib || geteuid() != 0)
|
||||
return respond(
|
||||
h, m, "{\"returnValue\":false,\"errorText\":\"Root service and JSON-C are required\"}");
|
||||
if (enabled && !piccap_installed())
|
||||
return respond(h, m, "{\"returnValue\":false,\"errorText\":\"PicCap is not installed\"}");
|
||||
if (!handover_save(enabled))
|
||||
return respond(
|
||||
h, m,
|
||||
"{\"returnValue\":false,\"errorText\":\"Could not save PicCap handover preference\"}");
|
||||
handover_enabled = enabled;
|
||||
protection = PLAYBACK_UNKNOWN;
|
||||
clear_samples = 0;
|
||||
clear_since = unknown_since = 0;
|
||||
next_media_probe = 0;
|
||||
return respond(h, m, "{\"returnValue\":true}");
|
||||
}
|
||||
static bool settings(void *h, void *m, void *ctx) {
|
||||
(void)ctx;
|
||||
TargetConfig next = target;
|
||||
if (!playback_json.lib || !target_parse(&playback_json, payload(m), &next))
|
||||
return respond(h, m,
|
||||
"{\"returnValue\":false,\"errorText\":\"Enter a valid IPv4/IPv6 address, "
|
||||
"integer port (1-65535), receiver and optional API token\"}");
|
||||
if (!target_save(TARGET_PREF, &next))
|
||||
return respond(
|
||||
h, m, "{\"returnValue\":false,\"errorText\":\"Could not save receiver settings\"}");
|
||||
bool active = capture || piccap_owned || retries.due;
|
||||
stop_capture();
|
||||
stream_close(milliseconds());
|
||||
bridge_phase = BRIDGE_IDLE;
|
||||
memset(&continuity, 0, sizeof(continuity));
|
||||
test_close();
|
||||
connection_test.stage = TEST_IDLE;
|
||||
target = next;
|
||||
last_error[0] = 0;
|
||||
protection = PLAYBACK_UNKNOWN;
|
||||
clear_samples = 0;
|
||||
clear_since = unknown_since = 0;
|
||||
if (active && !retries.paused && !retries.blocked)
|
||||
retries.due = milliseconds();
|
||||
return respond(h, m, "{\"returnValue\":true}");
|
||||
}
|
||||
static bool test_connection(void *h, void *m, void *ctx) {
|
||||
(void)ctx;
|
||||
if (strcmp(payload(m), "{}") || !playback_json.lib)
|
||||
return respond(
|
||||
h, m,
|
||||
"{\"returnValue\":false,\"errorText\":\"Test requires an empty object and JSON-C\"}");
|
||||
if (!test_begin(&target, milliseconds()))
|
||||
return respond(
|
||||
h, m, "{\"returnValue\":false,\"errorText\":\"A connection test is already running\"}");
|
||||
return respond(h, m, "{\"returnValue\":true,\"testing\":true}");
|
||||
}
|
||||
#include "service_status.h"
|
||||
Reference in new issue
Block a user