1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 //! host_usb
16 #![allow(missing_docs)]
17 #[cfg(feature = "host")]
18 extern crate ylong_runtime_static as ylong_runtime;
19 use crate::config;
20 use crate::config::*;
21 use crate::serializer;
22 use crate::serializer::native_struct::UsbHead;
23 use crate::serializer::serialize::Serialization;
24 use crate::serializer::serialize::SerializedBuffer;
25 use crate::transfer::base;
26 use crate::utils;
27 #[allow(unused)]
28 use crate::utils::hdc_log::*;
29
30 use crate::config::ConnectType;
31 use crate::config::TaskMessage;
32 use crate::transfer::base::Reader;
33 use crate::transfer::base::Writer;
34 use crate::transfer::buffer::ConnectTypeMap;
35 use std::collections::HashMap;
36 use std::io::{self, Error, ErrorKind};
37 use std::string::FromUtf8Error;
38 use std::sync::Arc;
39 use ylong_runtime::sync::mpsc;
40 use ylong_runtime::sync::mpsc::BoundedSender;
41 use ylong_runtime::sync::Mutex;
42 use ylong_runtime::sync::RwLock;
43 #[repr(C)]
44 pub struct PersistBuffer {
45 pub ptr: *const libc::c_char,
46 pub size: libc::c_ulonglong,
47 }
48
buf_to_vec(buf: PersistBuffer) -> Vec<u8>49 pub fn buf_to_vec(buf: PersistBuffer) -> Vec<u8> {
50 let slice =
51 unsafe { std::slice::from_raw_parts(buf.ptr as *const libc::c_uchar, buf.size as usize) };
52 slice.to_vec()
53 }
54
55 extern "C" {
InitHostUsb() -> *mut libc::c_void56 fn InitHostUsb() -> *mut libc::c_void;
GetReadyUsbDevice(ptr: *mut libc::c_void) -> PersistBuffer57 fn GetReadyUsbDevice(ptr: *mut libc::c_void) -> PersistBuffer;
OnDeviceConnected( ptr: *mut libc::c_void, connect_key: *mut libc::c_char, len: i32, connectSuccess: bool, )58 fn OnDeviceConnected(
59 ptr: *mut libc::c_void,
60 connect_key: *mut libc::c_char,
61 len: i32,
62 connectSuccess: bool,
63 );
WriteUsb( ptr: *mut libc::c_void, connect_key: *mut libc::c_char, len: i32, buf: SerializedBuffer, ) -> libc::c_int64 fn WriteUsb(
65 ptr: *mut libc::c_void,
66 connect_key: *mut libc::c_char,
67 len: i32,
68 buf: SerializedBuffer,
69 ) -> libc::c_int;
ReadUsb( ptr: *mut libc::c_void, connect_key: *mut libc::c_char, len: i32, excepted_size: i32, ) -> PersistBuffer70 fn ReadUsb(
71 ptr: *mut libc::c_void,
72 connect_key: *mut libc::c_char,
73 len: i32,
74 excepted_size: i32,
75 ) -> PersistBuffer;
CancelUsbIo(ptr: *mut libc::c_void, connect_key: *mut libc::c_char, len: i32)76 fn CancelUsbIo(ptr: *mut libc::c_void, connect_key: *mut libc::c_char, len: i32);
Stop(ptr: *mut libc::c_void) -> bool77 fn Stop(ptr: *mut libc::c_void) -> bool;
78 }
79
init_host_usb() -> *mut libc::c_void80 pub fn init_host_usb() -> *mut libc::c_void {
81 unsafe { InitHostUsb() }
82 }
83
get_ready_usb_devices_string(ptr: u64) -> Result<String, FromUtf8Error>84 pub fn get_ready_usb_devices_string(ptr: u64) -> Result<String, FromUtf8Error> {
85 let buf = get_ready_usb_devices(ptr);
86 String::from_utf8(buf_to_vec(buf))
87 }
88
get_ready_usb_devices(ptr: u64) -> PersistBuffer89 pub fn get_ready_usb_devices(ptr: u64) -> PersistBuffer {
90 unsafe { GetReadyUsbDevice(ptr as *mut libc::c_void) }
91 }
92
on_device_connected(ptr: u64, connect_key: String, connect_success: bool)93 pub fn on_device_connected(ptr: u64, connect_key: String, connect_success: bool) {
94 unsafe {
95 OnDeviceConnected(
96 ptr as *mut libc::c_void,
97 connect_key.as_str().as_ptr() as *mut libc::c_char,
98 connect_key.len() as i32,
99 connect_success,
100 );
101 }
102 }
103
write_usb(ptr: u64, connect_key: String, buf: SerializedBuffer) -> i32104 pub fn write_usb(ptr: u64, connect_key: String, buf: SerializedBuffer) -> i32 {
105 unsafe {
106 WriteUsb(
107 ptr as *mut libc::c_void,
108 connect_key.as_str().as_ptr() as *mut libc::c_char,
109 connect_key.len() as i32,
110 buf,
111 )
112 }
113 }
114
read_usb(ptr: u64, connect_key: String, excepted_size: i32) -> PersistBuffer115 pub fn read_usb(ptr: u64, connect_key: String, excepted_size: i32) -> PersistBuffer {
116 unsafe {
117 ReadUsb(
118 ptr as *mut libc::c_void,
119 connect_key.as_str().as_ptr() as *mut libc::c_char,
120 connect_key.len() as i32,
121 excepted_size,
122 )
123 }
124 }
125
cancel_usb_io(ptr: u64, connect_key: String)126 pub fn cancel_usb_io(ptr: u64, connect_key: String) {
127 unsafe {
128 CancelUsbIo(
129 ptr as *mut libc::c_void,
130 connect_key.as_str().as_ptr() as *mut libc::c_char,
131 connect_key.len() as i32,
132 );
133 }
134 }
135
stop(ptr: u64)136 pub fn stop(ptr: u64) {
137 unsafe {
138 Stop(ptr as *mut libc::c_void);
139 }
140 }
141
142 pub struct HostUsbReader {
143 pub connect_key: String,
144 pub ptr: u64,
145 }
146 pub struct HostUsbWriter {
147 pub connect_key: String,
148 pub ptr: u64,
149 }
150
151 impl base::Reader for HostUsbReader {
read_frame(&self, expected_size: usize) -> io::Result<Vec<u8>>152 fn read_frame(&self, expected_size: usize) -> io::Result<Vec<u8>> {
153 let buf = read_usb(self.ptr, self.connect_key.clone(), expected_size as i32);
154 if buf.size == 0 {
155 crate::warn!("usb read result < 0");
156 return Err(utils::error_other("usb read error".to_string()));
157 }
158
159 Ok(buf_to_vec(buf))
160 }
161
check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)>162 fn check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)> {
163 let buf = self.read_frame(serializer::USB_HEAD_SIZE)?;
164 if buf[..config::USB_PACKET_FLAG.len()] != config::USB_PACKET_FLAG[..] {
165 return Err(Error::new(
166 ErrorKind::Other,
167 format!("USB_PACKET_FLAG incorrect, content: {:#?}", buf),
168 ));
169 }
170 let mut head = serializer::native_struct::UsbHead::default();
171
172 if let Err(e) = head.parse(buf) {
173 crate::warn!("parse usb head error: {}", e.to_string());
174 return Err(e);
175 }
176 Ok((u32::from_be(head.data_size), 0, head.session_id))
177 }
178 }
179
180 impl base::Writer for HostUsbWriter {
write_all(&self, data: Vec<u8>) -> io::Result<i32>181 fn write_all(&self, data: Vec<u8>) -> io::Result<i32> {
182 let buf = SerializedBuffer {
183 ptr: data.as_ptr() as *const libc::c_char,
184 size: data.len() as u64,
185 };
186 let ret = write_usb(self.ptr, self.connect_key.clone(), buf);
187 if ret < 0 {
188 Err(utils::error_other("usb write failed".to_string()))
189 } else {
190 Ok(ret)
191 }
192 }
193 }
194
build_header(session_id: u32, option: u8, length: usize) -> Vec<u8>195 pub fn build_header(session_id: u32, option: u8, length: usize) -> Vec<u8> {
196 UsbHead {
197 session_id: u32::to_be(session_id),
198 flag: [config::USB_PACKET_FLAG[0], config::USB_PACKET_FLAG[1]],
199 option,
200 data_size: u32::to_be(length as u32),
201 }
202 .serialize()
203 }
204
recv_channel_message(rd: &mut HostUsbReader) -> io::Result<Vec<u8>>205 pub async fn recv_channel_message(rd: &mut HostUsbReader) -> io::Result<Vec<u8>> {
206 let data = rd.read_frame(4)?;
207 let expected_size = u32::from_be_bytes(data.try_into().unwrap());
208 rd.read_frame(expected_size as usize)
209 }
210
unpack_task_message( rd: &mut dyn Reader, tx: BoundedSender<(TaskMessage, u32)>, ) -> io::Result<()>211 async fn unpack_task_message(
212 rd: &mut dyn Reader,
213 tx: BoundedSender<(TaskMessage, u32)>,
214 ) -> io::Result<()> {
215 let (pack_size, package_index, _session_id) = rd.check_protocol_head()?;
216 if pack_size == 0 {
217 return Ok(());
218 }
219
220 let data = rd.read_frame(pack_size as usize)?;
221 let (head, body) = data.split_at(serializer::HEAD_SIZE);
222 let payload_head = serializer::unpack_payload_head(head.to_vec())?;
223 let expected_head_size = u16::from_be(payload_head.head_size) as usize;
224 let expected_data_size = u32::from_be(payload_head.data_size) as usize;
225
226 if serializer::HEAD_SIZE + expected_head_size + expected_data_size != pack_size as usize {
227 crate::warn!(
228 "protocol size diff: {pack_size} != {} + {expected_head_size} + {expected_data_size}",
229 serializer::HEAD_SIZE
230 );
231 }
232
233 if expected_head_size + expected_data_size == 0
234 || expected_head_size + expected_data_size > HDC_BUF_MAX_SIZE
235 {
236 return Err(Error::new(ErrorKind::Other, "Packet size incorrect"));
237 }
238
239 let (protect, payload_raw) = body.split_at(expected_head_size);
240 let (payload, _) = payload_raw.split_at(expected_data_size);
241
242 let payload_protect = serializer::unpack_payload_protect(protect.to_vec())?;
243 let channel_id = payload_protect.channel_id;
244
245 let command = match HdcCommand::try_from(payload_protect.command_flag) {
246 Ok(command) => command,
247 Err(_) => {
248 return Err(Error::new(ErrorKind::Other, "unknown command"));
249 }
250 };
251 let _ = tx
252 .send((
253 TaskMessage {
254 channel_id,
255 command,
256 payload: payload.to_vec(),
257 },
258 package_index,
259 ))
260 .await;
261 Ok(())
262 }
263
start_recv( ptr: u64, connect_key: String, _session_id: u32, ) -> mpsc::BoundedReceiver<(TaskMessage, u32)>264 pub fn start_recv(
265 ptr: u64,
266 connect_key: String,
267 _session_id: u32,
268 ) -> mpsc::BoundedReceiver<(TaskMessage, u32)> {
269 let (tx, rx) = mpsc::bounded_channel::<(TaskMessage, u32)>(config::USB_QUEUE_LEN);
270 ylong_runtime::spawn(async move {
271 let mut rd: HostUsbReader = HostUsbReader { connect_key, ptr };
272 loop {
273 if let Err(e) = unpack_task_message(&mut rd, tx.clone()).await {
274 crate::warn!("unpack task failed: {}, reopen fd...", e.to_string());
275 break;
276 }
277 }
278 });
279 rx
280 }
281
start_recv_once( ptr: u64, connect_key: String, _session_id: u32, ) -> mpsc::BoundedReceiver<(TaskMessage, u32)>282 pub fn start_recv_once(
283 ptr: u64,
284 connect_key: String,
285 _session_id: u32,
286 ) -> mpsc::BoundedReceiver<(TaskMessage, u32)> {
287 let (tx, rx) = mpsc::bounded_channel::<(TaskMessage, u32)>(config::USB_QUEUE_LEN);
288 ylong_runtime::spawn(async move {
289 let mut rd: HostUsbReader = HostUsbReader { connect_key, ptr };
290 if let Err(e) = unpack_task_message(&mut rd, tx.clone()).await {
291 crate::warn!("unpack task failed: {}, reopen fd...", e.to_string());
292 }
293 });
294 rx
295 }
296
297 type HostUsbWriter_ = Arc<Mutex<HostUsbWriter>>;
298 type HostUsbMap_ = Arc<RwLock<HashMap<u32, HostUsbWriter_>>>;
299
300 pub struct HostUsbMap {}
301 impl HostUsbMap {
get_instance() -> HostUsbMap_302 fn get_instance() -> HostUsbMap_ {
303 static mut USB_MAP: Option<HostUsbMap_> = None;
304 unsafe {
305 USB_MAP
306 .get_or_insert_with(|| Arc::new(RwLock::new(HashMap::new())))
307 .clone()
308 }
309 }
310
311 #[allow(unused)]
put(session_id: u32, data: TaskMessage) -> io::Result<()>312 pub async fn put(session_id: u32, data: TaskMessage) -> io::Result<()> {
313 let body = serializer::concat_pack(data);
314 crate::debug!("transfer put data {:?}", body);
315 let head = build_header(session_id, 1, body.len());
316 let tail = build_header(session_id, 0, 0);
317
318 let instance = Self::get_instance();
319 let map: ylong_runtime::sync::RwLockReadGuard<'_, HashMap<u32, Arc<Mutex<HostUsbWriter>>>> =
320 instance.read().await;
321 let arc_wr = map.get(&session_id).unwrap();
322 let mut wr = arc_wr.lock().await;
323 wr.write_all(head)?;
324 wr.write_all(body)?;
325 wr.write_all(tail)?;
326 Ok(())
327 }
328
329 #[allow(unused)]
send_channel_message(channel_id: u32, buf: Vec<u8>) -> io::Result<()>330 pub async fn send_channel_message(channel_id: u32, buf: Vec<u8>) -> io::Result<()> {
331 crate::trace!("send channel msg: {:#?}", buf.clone());
332 let send = [
333 u32::to_be_bytes(buf.len() as u32).as_slice(),
334 buf.as_slice(),
335 ]
336 .concat();
337 let instance = Self::get_instance();
338 let map = instance.read().await;
339 if let Some(guard) = map.get(&channel_id) {
340 let mut wr = guard.lock().await;
341 let _ = wr.write_all(send);
342 return Ok(());
343 }
344 Err(Error::new(ErrorKind::NotFound, "channel not found"))
345 }
346
start(session_id: u32, wr: HostUsbWriter)347 pub async fn start(session_id: u32, wr: HostUsbWriter) {
348 let buffer_map = Self::get_instance();
349 let mut map = buffer_map.write().await;
350 let arc_wr = Arc::new(Mutex::new(wr));
351 map.insert(session_id, arc_wr);
352 ConnectTypeMap::put(
353 session_id,
354 ConnectType::HostUsb("some_mount_point".to_string()),
355 )
356 .await;
357 }
358
359 #[allow(unused)]
end(id: u32)360 pub async fn end(id: u32) {
361 crate::warn!("usb session {} will end", id);
362 let instance = Self::get_instance();
363 let mut map = instance.write().await;
364 let _ = map.remove(&id);
365 ConnectTypeMap::del(id).await;
366 }
367 }
368