• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::fs::OpenOptions;
6 use std::path::Path;
7 use std::path::PathBuf;
8 
9 use base::open_file;
10 use remain::sorted;
11 use thiserror::Error;
12 
13 #[cfg(feature = "gpu")]
14 pub use crate::gpu::*;
15 pub use crate::sys::handle_request;
16 pub use crate::*;
17 
18 #[sorted]
19 #[derive(Error, Debug)]
20 enum ModifyBatError {
21     #[error("{0}")]
22     BatControlErr(BatControlResult),
23 }
24 
25 #[sorted]
26 #[derive(Error, Debug)]
27 pub enum ModifyUsbError {
28     #[error("failed to open device {0}: {1}")]
29     FailedToOpenDevice(PathBuf, base::Error),
30     #[error("socket failed")]
31     SocketFailed,
32     #[error("unexpected response: {0}")]
33     UnexpectedResponse(VmResponse),
34     #[error("{0}")]
35     UsbControl(UsbControlResult),
36 }
37 
38 pub type ModifyUsbResult<T> = std::result::Result<T, ModifyUsbError>;
39 
40 pub type VmsRequestResult = std::result::Result<(), ()>;
41 
42 /// Send a `VmRequest` that expects a `VmResponse::Ok` reply.
vms_request<T: AsRef<Path> + std::fmt::Debug>( request: &VmRequest, socket_path: T, ) -> VmsRequestResult43 pub fn vms_request<T: AsRef<Path> + std::fmt::Debug>(
44     request: &VmRequest,
45     socket_path: T,
46 ) -> VmsRequestResult {
47     match handle_request(request, socket_path)? {
48         VmResponse::Ok => Ok(()),
49         r => {
50             println!("unexpected response: {r}");
51             Err(())
52         }
53     }
54 }
55 
do_usb_attach<T: AsRef<Path> + std::fmt::Debug>( socket_path: T, dev_path: &Path, ) -> ModifyUsbResult<UsbControlResult>56 pub fn do_usb_attach<T: AsRef<Path> + std::fmt::Debug>(
57     socket_path: T,
58     dev_path: &Path,
59 ) -> ModifyUsbResult<UsbControlResult> {
60     let usb_file = open_file(dev_path, OpenOptions::new().read(true).write(true))
61         .map_err(|e| ModifyUsbError::FailedToOpenDevice(dev_path.into(), e))?;
62 
63     let request = VmRequest::UsbCommand(UsbControlCommand::AttachDevice { file: usb_file });
64     let response =
65         handle_request(&request, socket_path).map_err(|_| ModifyUsbError::SocketFailed)?;
66     match response {
67         VmResponse::UsbResponse(usb_resp) => Ok(usb_resp),
68         r => Err(ModifyUsbError::UnexpectedResponse(r)),
69     }
70 }
71 
do_usb_detach<T: AsRef<Path> + std::fmt::Debug>( socket_path: T, port: u8, ) -> ModifyUsbResult<UsbControlResult>72 pub fn do_usb_detach<T: AsRef<Path> + std::fmt::Debug>(
73     socket_path: T,
74     port: u8,
75 ) -> ModifyUsbResult<UsbControlResult> {
76     let request = VmRequest::UsbCommand(UsbControlCommand::DetachDevice { port });
77     let response =
78         handle_request(&request, socket_path).map_err(|_| ModifyUsbError::SocketFailed)?;
79     match response {
80         VmResponse::UsbResponse(usb_resp) => Ok(usb_resp),
81         r => Err(ModifyUsbError::UnexpectedResponse(r)),
82     }
83 }
84 
do_usb_list<T: AsRef<Path> + std::fmt::Debug>( socket_path: T, ) -> ModifyUsbResult<UsbControlResult>85 pub fn do_usb_list<T: AsRef<Path> + std::fmt::Debug>(
86     socket_path: T,
87 ) -> ModifyUsbResult<UsbControlResult> {
88     let mut ports: [u8; USB_CONTROL_MAX_PORTS] = Default::default();
89     for (index, port) in ports.iter_mut().enumerate() {
90         *port = index as u8
91     }
92     let request = VmRequest::UsbCommand(UsbControlCommand::ListDevice { ports });
93     let response =
94         handle_request(&request, socket_path).map_err(|_| ModifyUsbError::SocketFailed)?;
95     match response {
96         VmResponse::UsbResponse(usb_resp) => Ok(usb_resp),
97         r => Err(ModifyUsbError::UnexpectedResponse(r)),
98     }
99 }
100 
101 pub type DoModifyBatteryResult = std::result::Result<(), ()>;
102 
do_modify_battery<T: AsRef<Path> + std::fmt::Debug>( socket_path: T, battery_type: &str, property: &str, target: &str, ) -> DoModifyBatteryResult103 pub fn do_modify_battery<T: AsRef<Path> + std::fmt::Debug>(
104     socket_path: T,
105     battery_type: &str,
106     property: &str,
107     target: &str,
108 ) -> DoModifyBatteryResult {
109     let response = match battery_type.parse::<BatteryType>() {
110         Ok(type_) => match BatControlCommand::new(property.to_string(), target.to_string()) {
111             Ok(cmd) => {
112                 let request = VmRequest::BatCommand(type_, cmd);
113                 Ok(handle_request(&request, socket_path)?)
114             }
115             Err(e) => Err(ModifyBatError::BatControlErr(e)),
116         },
117         Err(e) => Err(ModifyBatError::BatControlErr(e)),
118     };
119 
120     match response {
121         Ok(response) => {
122             println!("{}", response);
123             Ok(())
124         }
125         Err(e) => {
126             println!("error {}", e);
127             Err(())
128         }
129     }
130 }
131 
do_swap_status<T: AsRef<Path> + std::fmt::Debug>(socket_path: T) -> VmsRequestResult132 pub fn do_swap_status<T: AsRef<Path> + std::fmt::Debug>(socket_path: T) -> VmsRequestResult {
133     let response = handle_request(&VmRequest::Swap(SwapCommand::Status), socket_path)?;
134     match &response {
135         VmResponse::SwapStatus(_) => {
136             println!("{}", response);
137             Ok(())
138         }
139         r => {
140             println!("unexpected response: {r:?}");
141             Err(())
142         }
143     }
144 }
145 
146 pub type HandleRequestResult = std::result::Result<VmResponse, ()>;
147