1 use core::fmt::Debug; 2 3 use alloc::sync::{Arc, Weak}; 4 use kdepends::thingbuf::mpsc; 5 use system_error::SystemError; 6 7 use crate::{ 8 libs::spinlock::{SpinLock, SpinLockGuard}, 9 net::event_poll::EventPoll, 10 }; 11 12 use super::tty_core::TtyCore; 13 14 const TTY_PORT_BUFSIZE: usize = 4096; 15 16 #[allow(dead_code)] 17 #[derive(Debug)] 18 pub struct TtyPortData { 19 flags: i32, 20 iflags: TtyPortState, 21 sender: mpsc::Sender<u8>, 22 receiver: mpsc::Receiver<u8>, 23 tty: Weak<TtyCore>, 24 /// 内部tty,即与port直接相连的 25 internal_tty: Weak<TtyCore>, 26 } 27 28 impl Default for TtyPortData { 29 fn default() -> Self { 30 Self::new() 31 } 32 } 33 34 impl TtyPortData { 35 pub fn new() -> Self { 36 let (sender, receiver) = mpsc::channel::<u8>(TTY_PORT_BUFSIZE); 37 Self { 38 flags: 0, 39 iflags: TtyPortState::Initialized, 40 sender, 41 receiver, 42 tty: Weak::new(), 43 internal_tty: Weak::new(), 44 } 45 } 46 47 pub fn internal_tty(&self) -> Option<Arc<TtyCore>> { 48 self.internal_tty.upgrade() 49 } 50 51 pub fn tty(&self) -> Option<Arc<TtyCore>> { 52 self.tty.upgrade() 53 } 54 } 55 56 #[allow(dead_code)] 57 #[derive(Debug, PartialEq, Clone, Copy)] 58 pub enum TtyPortState { 59 Initialized, 60 Suspended, 61 Active, 62 CtsFlow, 63 CheckCD, 64 KOPENED, 65 } 66 67 pub trait TtyPort: Sync + Send + Debug { 68 fn port_data(&self) -> SpinLockGuard<TtyPortData>; 69 70 /// 获取Port的状态 71 fn state(&self) -> TtyPortState { 72 self.port_data().iflags 73 } 74 75 /// 为port设置tty 76 fn setup_internal_tty(&self, tty: Weak<TtyCore>) { 77 self.port_data().internal_tty = tty; 78 } 79 80 /// 作为客户端的tty ports接收数据 81 fn receive_buf(&self, buf: &[u8], _flags: &[u8], count: usize) -> Result<usize, SystemError> { 82 let tty = self.port_data().internal_tty().unwrap(); 83 84 let ld = tty.ldisc(); 85 86 let ret = ld.receive_buf2(tty.clone(), buf, None, count); 87 if ret.is_err() && ret.clone().unwrap_err() == SystemError::ENOSYS { 88 return ld.receive_buf(tty, buf, None, count); 89 } 90 91 EventPoll::wakeup_epoll(tty.core().eptiems(), None)?; 92 93 ret 94 } 95 } 96 97 #[derive(Debug)] 98 pub struct DefaultTtyPort { 99 port_data: SpinLock<TtyPortData>, 100 } 101 102 impl DefaultTtyPort { 103 pub fn new() -> Self { 104 Self { 105 port_data: SpinLock::new(TtyPortData::new()), 106 } 107 } 108 } 109 110 impl TtyPort for DefaultTtyPort { 111 fn port_data(&self) -> SpinLockGuard<TtyPortData> { 112 self.port_data.lock_irqsave() 113 } 114 } 115