119 lines
4.7 KiB
Rust
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:#}")))
|
|
}
|
|
}
|