• 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 //! usb
16 #![allow(missing_docs)]
17 
18 use super::base;
19 
20 use crate::config;
21 use crate::serializer;
22 use crate::serializer::native_struct::UsbHead;
23 use crate::serializer::pack_struct::UsbHeadPack;
24 use crate::serializer::serialize::Serialization;
25 use crate::serializer::serialize::SerializedBuffer;
26 use crate::utils;
27 #[allow(unused)]
28 use crate::utils::hdc_log::*;
29 
30 #[cfg(not(target_os = "windows"))]
31 use std::ffi::{CStr, CString};
32 use std::io::{self, Error, ErrorKind};
33 #[cfg(not(feature = "host"))]
34 use libc::{fcntl, F_SETFD, FD_CLOEXEC};
35 
36 #[repr(C)]
37 pub struct PersistBuffer {
38     pub ptr: *const libc::c_char,
39     pub size: libc::c_ulonglong,
40 }
41 
buf_to_vec(buf: PersistBuffer) -> Vec<u8>42 pub fn buf_to_vec(buf: PersistBuffer) -> Vec<u8> {
43     let slice =
44         unsafe { std::slice::from_raw_parts(buf.ptr as *const libc::c_uchar, buf.size as usize) };
45     slice.to_vec()
46 }
47 
48 #[allow(unused)]
49 extern "C" {
access(_name: *const libc::c_char, _type: i32) -> i3250     fn access(_name: *const libc::c_char, _type: i32) -> i32;
free(ptr: *const libc::c_void)51     fn free(ptr: *const libc::c_void);
52 
ConfigEpPointEx(path: *const libc::c_char) -> i3253     fn ConfigEpPointEx(path: *const libc::c_char) -> i32;
OpenEpPointEx(path: *const libc::c_char) -> i3254     fn OpenEpPointEx(path: *const libc::c_char) -> i32;
CloseUsbFdEx(fd: i32) -> i3255     fn CloseUsbFdEx(fd: i32) -> i32;
CloseEndPointEx(bulkIn: i32, bulkOut: i32, ctrlEp: i32, closeCtrlEp: u8)56     fn CloseEndPointEx(bulkIn: i32, bulkOut: i32, ctrlEp: i32, closeCtrlEp: u8);
57     #[cfg(not(target_os = "windows"))]
WriteUsbDevEx(bulkOut: i32, buf: SerializedBuffer) -> i3258     fn WriteUsbDevEx(bulkOut: i32, buf: SerializedBuffer) -> i32;
59     #[cfg(not(target_os = "windows"))]
ReadUsbDevEx(bulkIn: i32, buf: *mut u8, size: usize) -> usize60     fn ReadUsbDevEx(bulkIn: i32, buf: *mut u8, size: usize) -> usize;
GetDevPathEx(path: *const libc::c_char) -> *const libc::c_char61     fn GetDevPathEx(path: *const libc::c_char) -> *const libc::c_char;
62 
SerializeUsbHead(value: *const UsbHeadPack) -> SerializedBuffer63     fn SerializeUsbHead(value: *const UsbHeadPack) -> SerializedBuffer;
ParseUsbHead(value: *mut UsbHeadPack, buf: SerializedBuffer) -> libc::c_uchar64     fn ParseUsbHead(value: *mut UsbHeadPack, buf: SerializedBuffer) -> libc::c_uchar;
65 }
66 
67 #[cfg(not(target_os = "windows"))]
usb_init() -> io::Result<(i32, i32, i32)>68 pub fn usb_init() -> io::Result<(i32, i32, i32)> {
69     crate::info!("opening usb fd...");
70     let path = CString::new(config::USB_FFS_BASE).unwrap();
71 
72     let base_path = unsafe {
73         let p = GetDevPathEx(path.as_ptr());
74         let c_str = CStr::from_ptr(p);
75         c_str.to_str().unwrap().to_string()
76     };
77     // let c_str: &CStr = unsafe { CStr::from_ptr(p) };
78     // c_str.to_str().unwrap().to_string()
79     // let base_path = serializer::ptr_to_string(unsafe { GetDevPathEx(path.as_ptr()) });
80     let ep0 = CString::new(base_path.clone() + "/ep0").unwrap();
81     let ep1 = CString::new(base_path.clone() + "/ep1").unwrap();
82     let ep2 = CString::new(base_path + "/ep2").unwrap();
83     if unsafe { access(ep0.as_ptr(), 0) } != 0 {
84         return Err(utils::error_other("cannot access usb path".to_string()));
85     }
86 
87     let config_fd = unsafe { ConfigEpPointEx(ep0.as_ptr()) };
88     if config_fd < 0 {
89         return Err(utils::error_other("cannot open usb ep0".to_string()));
90     }
91 
92     let bulkin_fd = unsafe { OpenEpPointEx(ep1.as_ptr()) };
93     if bulkin_fd < 0 {
94         return Err(utils::error_other("cannot open usb ep1".to_string()));
95     }
96 
97     let bulkout_fd = unsafe { OpenEpPointEx(ep2.as_ptr()) };
98     if bulkout_fd < 0 {
99         return Err(utils::error_other("cannot open usb ep2".to_string()));
100     }
101     #[cfg(not(feature = "host"))]
102     unsafe{
103         // cannot open with O_CLOEXEC, must fcntl
104         fcntl(config_fd, F_SETFD, FD_CLOEXEC);
105         fcntl(bulkin_fd, F_SETFD, FD_CLOEXEC);
106         fcntl(bulkout_fd, F_SETFD, FD_CLOEXEC);
107     }
108 
109     crate::info!("usb fd: {config_fd}, {bulkin_fd}, {bulkout_fd}");
110 
111     Ok((config_fd, bulkin_fd, bulkout_fd))
112 }
113 
114 #[cfg(not(target_os = "windows"))]
usb_close(config_fd: i32, bulkin_fd: i32, bulkout_fd: i32)115 pub fn usb_close(config_fd: i32, bulkin_fd: i32, bulkout_fd: i32) {
116     crate::info!("closing usb fd...");
117     unsafe {
118         CloseUsbFdEx(config_fd);
119         CloseUsbFdEx(bulkin_fd);
120         CloseUsbFdEx(bulkout_fd);
121     }
122 }
123 
124 pub struct UsbReader {
125     pub fd: i32,
126 }
127 pub struct UsbWriter {
128     pub fd: i32,
129 }
130 
131 impl base::Reader for UsbReader {
132     // 屏蔽window编译报错
133     #[cfg(not(target_os = "windows"))]
read_frame(&self, expect: usize) -> io::Result<Vec<u8>>134     fn read_frame(&self, expect: usize) -> io::Result<Vec<u8>> {
135         let mut buf :Vec<u8> = Vec::with_capacity(expect);
136         unsafe {
137             let readed = ReadUsbDevEx(self.fd, buf.as_mut_ptr() as *mut libc::uint8_t, expect);
138             if readed != expect {
139                 Err(
140                     utils::error_other(
141                         format!(
142                             "usb read error, usb read failed: expect: {} acture: {}",
143                             expect,
144                             readed,
145                         )
146                     )
147                 )
148             } else {
149                 buf.set_len(readed);
150                 Ok(buf)
151             }
152         }
153     }
154 
155     // 屏蔽window编译报错
156     #[cfg(target_os = "windows")]
read_frame(&self, _expected_size: usize) -> io::Result<Vec<u8>>157     fn read_frame(&self, _expected_size: usize) -> io::Result<Vec<u8>> {
158         Err(utils::error_other("usb read error".to_string()))
159     }
160 
check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)>161     fn check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)> {
162         let buf = self.read_frame(serializer::USB_HEAD_SIZE)?;
163         if buf[..config::USB_PACKET_FLAG.len()] != config::USB_PACKET_FLAG[..] {
164             return Err(Error::new(
165                 ErrorKind::Other,
166                 format!("USB_PACKET_FLAG incorrect, content: {:#?}", buf),
167             ));
168         }
169         let mut head = serializer::native_struct::UsbHead::default();
170 
171         if let Err(e) = head.parse(buf) {
172             crate::warn!("parse usb head error: {}", e.to_string());
173             return Err(e);
174         }
175         Ok((u32::from_be(head.data_size), 0, u32::to_be(head.session_id)))
176     }
177 }
178 
179 #[cfg(not(target_os = "windows"))]
usb_write_all(fd: i32, data: Vec<u8>) -> io::Result<i32>180 pub fn usb_write_all(fd: i32, data: Vec<u8>) -> io::Result<i32> {
181     let buf = SerializedBuffer {
182         ptr: data.as_ptr() as *const libc::c_char,
183         size: data.len() as u64,
184     };
185     let ret = unsafe { WriteUsbDevEx(fd, buf) } as i32;
186     if ret < 0 {
187         Err(utils::error_other("usb write failed".to_string()))
188     } else {
189         Ok(ret)
190     }
191 }
192 impl base::Writer for UsbWriter {
193     // 屏蔽window编译报错
194     #[cfg(not(target_os = "windows"))]
195     #[allow(unused)]
write_all(&self, data: Vec<u8>) -> io::Result<i32>196     fn write_all(&self, data: Vec<u8>) -> io::Result<i32> {
197         let buf = SerializedBuffer {
198             ptr: data.as_ptr() as *const libc::c_char,
199             size: data.len() as u64,
200         };
201         let ret = unsafe { WriteUsbDevEx(self.fd, buf) } as i32;
202         if ret < 0 {
203             Err(utils::error_other("usb write failed".to_string()))
204         } else {
205             Ok(ret)
206         }
207     }
208 
209     // 屏蔽window编译报错
210     #[cfg(target_os = "windows")]
write_all(&self, _data: Vec<u8>) -> io::Result<i32>211     fn write_all(&self, _data: Vec<u8>) -> io::Result<i32> {
212         Ok(0)
213     }
214 }
215 
build_header(session_id: u32, option: u8, length: usize) -> Vec<u8>216 pub fn build_header(session_id: u32, option: u8, length: usize) -> Vec<u8> {
217     UsbHead {
218         session_id: u32::to_be(session_id),
219         flag: [config::USB_PACKET_FLAG[0], config::USB_PACKET_FLAG[1]],
220         option,
221         data_size: u32::to_be(length as u32),
222     }
223     .serialize()
224 }
225