lesavka/server/src/main/rpc_helpers.rs

119 lines
4.7 KiB
Rust

impl Handler {
async fn paste_text_reply(
&self,
req: Request<PasteRequest>,
) -> Result<Response<PasteReply>, Status> {
let req = req.into_inner();
let text = paste::decrypt(&req).map_err(|e| Status::unauthenticated(format!("{e}")))?;
if let Err(e) = paste::type_text(&self.kb, &hid_endpoint(0), &text).await {
return Ok(Response::new(PasteReply {
ok: false,
error: format!("{e}"),
}));
}
Ok(Response::new(PasteReply {
ok: true,
error: String::new(),
}))
}
async fn reset_usb_reply(&self) -> Result<Response<ResetUsbReply>, Status> {
#[cfg(not(coverage))]
info!("🔴 explicit ResetUsb() called");
match self.gadget.recover_enumeration() {
Ok(_) => {
if let Err(e) = self.reopen_hid().await {
#[cfg(not(coverage))]
error!("💥 reopen HID failed: {e:#}");
return Err(Status::internal(e.to_string()));
}
if let Err(e) = restart_uvc_helper() {
#[cfg(not(coverage))]
error!("💥 restart UVC helper failed: {e:#}");
return Err(Status::internal(e.to_string()));
}
match current_controller_state_after_recovery() {
Ok((ctrl, state)) if UsbGadget::host_enumerated_state(&state) => {
#[cfg(not(coverage))]
info!(
"✅ USB host enumerated gadget after recovery ctrl={ctrl} state={state}"
);
}
Ok((ctrl, state)) => {
let message = format!(
"USB gadget recovery ran, but UDC {ctrl} is still {state}; the controlled host has not enumerated the relay HID/audio/video gadget"
);
#[cfg(not(coverage))]
warn!("⚠️ {message}");
return Err(Status::failed_precondition(message));
}
Err(err) => {
let message = format!(
"USB gadget recovery ran, but the relay cannot read UDC state: {err:#}"
);
#[cfg(not(coverage))]
warn!("⚠️ {message}");
return Err(Status::failed_precondition(message));
}
}
Ok(Response::new(ResetUsbReply { ok: true }))
}
Err(e) => {
#[cfg(not(coverage))]
error!("💥 USB recovery failed: {e:#}");
let message = format!("{e:#}");
if message.contains("still not attached") || message.contains("not attached") {
Err(Status::failed_precondition(message))
} else {
Err(Status::internal(message))
}
}
}
}
async fn get_capture_power_reply(&self) -> Result<Response<CapturePowerState>, Status> {
let state = self
.capture_power
.snapshot()
.await
.map_err(|e| Status::internal(format!("{e:#}")))?;
Ok(Response::new(
self.with_detected_capture_devices(state).await,
))
}
async fn set_capture_power_reply(
&self,
req: Request<SetCapturePowerRequest>,
) -> Result<Response<CapturePowerState>, Status> {
let req = req.into_inner();
let result = match CapturePowerCommand::try_from(req.command)
.unwrap_or(CapturePowerCommand::Unspecified)
{
CapturePowerCommand::Auto => self.capture_power.set_auto().await,
CapturePowerCommand::ForceOn => self.capture_power.set_manual(true).await,
CapturePowerCommand::ForceOff => self.capture_power.set_manual(false).await,
CapturePowerCommand::Unspecified => self.capture_power.set_manual(req.enabled).await,
};
let state = result.map_err(|e| Status::internal(format!("{e:#}")))?;
Ok(Response::new(
self.with_detected_capture_devices(state).await,
))
}
async fn get_calibration_reply(&self) -> Result<Response<CalibrationState>, Status> {
Ok(Response::new(self.calibration.current()))
}
async fn calibrate_reply(
&self,
req: Request<CalibrationRequest>,
) -> Result<Response<CalibrationState>, Status> {
self.calibration
.apply(req.into_inner())
.map(Response::new)
.map_err(|e| Status::internal(format!("{e:#}")))
}
}