• 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 //! uart
16 #![allow(missing_docs)]
17 
18 use super::base;
19 
20 use super::uart_wrapper;
21 use crate::config;
22 use crate::serializer;
23 #[allow(unused)]
24 use crate::serializer::native_struct::UartHead;
25 use crate::serializer::serialize::Serialization;
26 use crate::serializer::serialize::SerializedBuffer;
27 use crate::utils;
28 #[allow(unused)]
29 use crate::utils::hdc_log::*;
30 
31 #[cfg(not(target_os = "windows"))]
32 use std::ffi::CString;
33 use std::io::{self, Error, ErrorKind};
34 
35 #[cfg(feature = "host")]
36 extern crate ylong_runtime_static as ylong_runtime;
37 use ylong_runtime::task::JoinHandle;
38 
39 #[allow(unused)]
40 extern "C" {
access(_name: *const libc::c_char, _type: i32) -> i3241     fn access(_name: *const libc::c_char, _type: i32) -> i32;
free(ptr: *const libc::c_void)42     fn free(ptr: *const libc::c_void);
43 
44     #[cfg(not(target_os = "windows"))]
GetUartSpeedExt(speed: i32) -> i3245     fn GetUartSpeedExt(speed: i32) -> i32;
46     #[cfg(not(target_os = "windows"))]
GetUartBitsExt(bits: i32) -> i3247     fn GetUartBitsExt(bits: i32) -> i32;
OpenSerialPortExt(port: *const libc::c_char) -> i3248     fn OpenSerialPortExt(port: *const libc::c_char) -> i32;
SetSerialExt(fd: i32, speed: i32, bits: i32, event: u8, stop: i32) -> i3249     fn SetSerialExt(fd: i32, speed: i32, bits: i32, event: u8, stop: i32) -> i32;
ReadUartDevExt(fd: i32, size: i32) -> SerializedBuffer50     fn ReadUartDevExt(fd: i32, size: i32) -> SerializedBuffer;
WriteUartDevExt(fd: i32, buf: SerializedBuffer) -> i3251     fn WriteUartDevExt(fd: i32, buf: SerializedBuffer) -> i32;
CloseSerialPortExt(fd: i32) -> u852     fn CloseSerialPortExt(fd: i32) -> u8;
53 }
54 
55 #[cfg(not(target_os = "windows"))]
uart_init() -> io::Result<i32>56 pub fn uart_init() -> io::Result<i32> {
57     let name = CString::new(config::UART_NODE).unwrap();
58     let fd = unsafe {
59         if access(name.as_ptr(), 0) != 0 {
60             return Err(utils::error_other("cannot access uart node".to_string()));
61         }
62         let fd = OpenSerialPortExt(name.as_ptr());
63         if fd < 0 {
64             return Err(utils::error_other("cannot open uart node".to_string()));
65         }
66         if SetSerialExt(
67             fd,
68             config::UART_DEFAULT_BAUD_RATE,
69             config::UART_DEFAULT_BITS,
70             config::UART_EVENT,
71             1,
72         ) != 0
73         {
74             return Err(utils::error_other("set uart config failed".to_string()));
75         }
76         crate::debug!("uart init fd: {fd}");
77         fd
78     };
79     Ok(fd)
80 }
81 
uart_close(_fd: i32)82 pub fn uart_close(_fd: i32) {
83     #[cfg(not(target_os = "windows"))]
84     unsafe {
85         CloseSerialPortExt(_fd);
86     }
87     #[cfg(target_os = "windows")]
88     return {};
89 }
90 
91 pub struct UartReader {
92     pub fd: i32,
93     pub head: Option<UartHead>,
94 }
95 
96 pub struct UartWriter {
97     pub fd: i32,
98 }
99 
100 impl base::Reader for UartReader {
read_frame(&self, expected_size: usize) -> io::Result<Vec<u8>>101     fn read_frame(&self, expected_size: usize) -> io::Result<Vec<u8>> {
102         if expected_size == 0 {
103             return Ok(vec![]);
104         }
105         let mut data = vec![];
106         let mut index = 0;
107         while index < expected_size {
108             crate::trace!("before read {index} / {expected_size}");
109             let buf = unsafe {
110                 let recv = ReadUartDevExt(self.fd, (expected_size - index) as i32);
111                 let slice = std::slice::from_raw_parts(
112                     recv.ptr as *const libc::c_uchar,
113                     recv.size as usize,
114                 );
115                 index += recv.size as usize;
116                 slice.to_vec()
117             };
118             data = [data, buf].concat();
119         }
120         Ok(data)
121     }
122 
check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)>123     fn check_protocol_head(&mut self) -> io::Result<(u32, u32, u32)> {
124         let buf = self.read_frame(serializer::UART_HEAD_SIZE)?;
125         if buf[..config::PACKET_FLAG.len()] != config::PACKET_FLAG[..] {
126             return Err(Error::new(
127                 ErrorKind::Other,
128                 format!("uart PACKET_FLAG incorrect, content: {:#?}", buf),
129             ));
130         }
131         let mut head = serializer::native_struct::UartHead::default();
132 
133         if let Err(e) = head.parse(buf) {
134             log::warn!("parse uart head error: {}", e.to_string());
135             return Err(e);
136         }
137 
138         self.head = Some(head.clone());
139 
140         Ok((head.data_size, head.package_index, head.session_id))
141     }
142 
143     #[allow(unused)]
process_head(&self) -> Option<JoinHandle<()>>144     fn process_head(&self) -> Option<JoinHandle<()>> {
145         let head = self.head.clone();
146         if let Some(head) = head {
147             let join_handle = utils::spawn(async move {
148                 uart_wrapper::on_read_head(head).await;
149             });
150             Some(join_handle)
151         } else {
152             None
153         }
154     }
155 }
156 
157 impl base::Writer for UartWriter {
write_all(&self, data: Vec<u8>) -> io::Result<i32>158     fn write_all(&self, data: Vec<u8>) -> io::Result<i32> {
159         let buf = SerializedBuffer {
160             ptr: data.as_ptr() as *const libc::c_char,
161             size: data.len() as u64,
162         };
163         crate::debug!("write all start, fd:{}...", self.fd);
164         let write_count = unsafe { WriteUartDevExt(self.fd, buf) } as i32;
165         crate::debug!("write count:{}", write_count);
166         if write_count < 0 {
167             Err(utils::error_other("uart write failed".to_string()))
168         } else {
169             Ok(write_count)
170         }
171     }
172 }
173 
build_header(session_id: u32, option: u16, length: usize, package_index: u32) -> Vec<u8>174 pub fn build_header(session_id: u32, option: u16, length: usize, package_index: u32) -> Vec<u8> {
175     UartHead {
176         session_id: u32::to_le(session_id),
177         flag: [config::PACKET_FLAG[0], config::PACKET_FLAG[1]],
178         option,
179         data_size: u32::to_le(length as u32),
180         package_index,
181         data_checksum: 0,
182         head_checksum: 0,
183     }
184     .serialize()
185 }
186 
build_header_obj( session_id: u32, option: u16, length: usize, package_index: u32, ) -> UartHead187 pub fn build_header_obj(
188     session_id: u32,
189     option: u16,
190     length: usize,
191     package_index: u32,
192 ) -> UartHead {
193     UartHead {
194         session_id: u32::to_le(session_id),
195         flag: [config::PACKET_FLAG[0], config::PACKET_FLAG[1]],
196         option,
197         data_size: u32::to_le(length as u32),
198         package_index,
199         data_checksum: 0,
200         head_checksum: 0,
201     }
202 }
203