• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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