1- use super :: logs:: advance;
21use crate :: args:: MonitorArgs ;
32use crate :: net:: connect;
3+ use crate :: serial:: { is_timeout, SerialStream } ;
44use anyhow:: { Context , Result } ;
55use crossterm:: { cursor, event, execute, style, terminal} ;
66use firefly_types:: { serial, Encode } ;
@@ -15,8 +15,6 @@ const RBORD: u16 = 21;
1515const KB : u32 = 1024 ;
1616const MB : u32 = 1024 * KB ;
1717
18- type Port = Box < dyn serialport:: SerialPort > ;
19-
2018#[ derive( Default ) ]
2119struct Stats {
2220 update : Option < serial:: Fuel > ,
@@ -54,35 +52,18 @@ pub fn cmd_monitor(_vfs: &Path, args: &MonitorArgs) -> Result<()> {
5452}
5553
5654fn monitor_device ( port : & str , args : & MonitorArgs ) -> Result < ( ) > {
57- let mut port = connect_device ( port, args) ?;
55+ let mut stream = connect_device ( port, args) ?;
5856 let mut stats = Stats :: default ( ) ;
59- request_device_stats ( & mut port, & mut stats) ?;
60- let mut buf = Vec :: new ( ) ;
57+ request_device_stats ( & mut stream, & mut stats) ?;
6158 loop {
6259 if should_exit ( ) {
6360 return Ok ( ( ) ) ;
6461 }
65- buf = read_device ( & mut port , buf , & mut stats) ?;
62+ read_device ( & mut stream , & mut stats) ?;
6663 render_stats ( & stats) . context ( "render stats" ) ?;
6764 }
6865}
6966
70- /// Connect to running emulator using serial USB port (JTag-over-USB).
71- fn connect_device ( port : & str , args : & MonitorArgs ) -> Result < Port > {
72- let port = serialport:: new ( port, args. baud_rate )
73- . timeout ( Duration :: from_millis ( 10 ) )
74- . open ( )
75- . context ( "open the serial port" ) ?;
76-
77- execute ! (
78- io:: stdout( ) ,
79- terminal:: Clear ( terminal:: ClearType :: All ) ,
80- cursor:: MoveTo ( 0 , 0 ) ,
81- style:: Print ( "waiting for stats..." ) ,
82- ) ?;
83- Ok ( port)
84- }
85-
8667fn monitor_emulator ( ) -> Result < ( ) > {
8768 let mut stream = connect_emulator ( ) ?;
8869 let mut stats = Stats :: default ( ) ;
@@ -103,39 +84,29 @@ fn read_emulator(mut stream: TcpStream, stats: &mut Stats) -> Result<TcpStream>
10384 let stream = connect ( ) . context ( "reconnecting" ) ?;
10485 return Ok ( stream) ;
10586 }
106- parse_stats ( stats, & buf[ ..size] ) ?;
87+ let resp = serial:: Response :: decode ( & buf[ ..size] ) . context ( "decode response" ) ?;
88+ parse_stats ( stats, resp) ;
10789 Ok ( stream)
10890}
10991
11092/// Receive and parse one stats message from device.
111- fn read_device ( port : & mut Port , mut buf : Vec < u8 > , stats : & mut Stats ) -> Result < Vec < u8 > > {
112- let mut chunk = vec ! [ 0 ; 64 ] ;
113- let n = match port. read ( chunk. as_mut_slice ( ) ) {
114- Ok ( n) => n,
93+ fn read_device ( stream : & mut SerialStream , stats : & mut Stats ) -> Result < ( ) > {
94+ match stream. next ( ) {
95+ Ok ( resp) => {
96+ parse_stats ( stats, resp) ;
97+ stats. last_msg = Some ( Instant :: now ( ) ) ;
98+ }
11599 Err ( err) => {
116- if err. kind ( ) == std:: io:: ErrorKind :: TimedOut {
117- request_device_stats ( port, stats) ?;
118- return Ok ( buf) ;
100+ if !is_timeout ( & err) {
101+ return Err ( err) ;
119102 }
120- return Err ( err) . context ( "read from serial port" ) ;
121103 }
122- } ;
123-
124- stats. last_msg = Some ( Instant :: now ( ) ) ;
125- buf. extend_from_slice ( & chunk[ ..n] ) ;
126- loop {
127- let ( frame, rest) = advance ( & buf) ;
128- buf = Vec :: from ( rest) ;
129- if frame. is_empty ( ) {
130- break ;
131- }
132- parse_stats ( stats, & frame) ?;
133104 }
134- Ok ( buf )
105+ Ok ( ( ) )
135106}
136107
137108/// Send a message into the running device requesting to enable stats collection.
138- fn request_device_stats ( port : & mut Port , stats : & mut Stats ) -> Result < ( ) > {
109+ fn request_device_stats ( stream : & mut SerialStream , stats : & mut Stats ) -> Result < ( ) > {
139110 let now = Instant :: now ( ) ;
140111 let should_update = match stats. last_msg {
141112 Some ( last_msg) => {
@@ -148,16 +119,12 @@ fn request_device_stats(port: &mut Port, stats: &mut Stats) -> Result<()> {
148119 if should_update {
149120 stats. last_msg = Some ( now) ;
150121 let req = serial:: Request :: Stats ( true ) ;
151- let buf = req. encode_vec ( ) . context ( "encode request" ) ?;
152- port. write_all ( & buf[ ..] ) . context ( "send request" ) ?;
153- port. flush ( ) . context ( "flush request" ) ?;
122+ stream. send ( & req) ?;
154123 }
155124 Ok ( ( ) )
156125}
157126
158- /// Parse raw stats message using postcard. Does NOT handle COBS frames.
159- fn parse_stats ( stats : & mut Stats , buf : & [ u8 ] ) -> Result < ( ) > {
160- let resp = serial:: Response :: decode ( buf) . context ( "decode response" ) ?;
127+ fn parse_stats ( stats : & mut Stats , resp : serial:: Response ) {
161128 match resp {
162129 serial:: Response :: Cheat ( _) => { }
163130 serial:: Response :: Log ( log) => {
@@ -180,7 +147,22 @@ fn parse_stats(stats: &mut Stats, buf: &[u8]) -> Result<()> {
180147 }
181148 serial:: Response :: Memory ( mem) => stats. mem = Some ( mem) ,
182149 }
183- Ok ( ( ) )
150+ }
151+
152+ /// Connect to running emulator using serial USB port (JTag-over-USB).
153+ fn connect_device ( port : & str , args : & MonitorArgs ) -> Result < SerialStream > {
154+ let port = serialport:: new ( port, args. baud_rate )
155+ . timeout ( Duration :: from_millis ( 10 ) )
156+ . open ( )
157+ . context ( "open the serial port" ) ?;
158+
159+ execute ! (
160+ io:: stdout( ) ,
161+ terminal:: Clear ( terminal:: ClearType :: All ) ,
162+ cursor:: MoveTo ( 0 , 0 ) ,
163+ style:: Print ( "waiting for stats..." ) ,
164+ ) ?;
165+ Ok ( SerialStream :: new ( port) )
184166}
185167
186168/// Connect to a running emulator and enable stats.
0 commit comments