Skip to content
This repository was archived by the owner on Dec 15, 2021. It is now read-only.

Commit b76b56a

Browse files
author
Alex Helfet
committed
Extract read_packet() function.
1 parent 9af4f0d commit b76b56a

File tree

3 files changed

+108
-48
lines changed

3 files changed

+108
-48
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ chrono = "^0.4"
1414
clap = "^2.14.0"
1515
env_logger = "^0.4.3"
1616
error-chain = "^0.11.0"
17+
heapless = "^0.2.0"
1718
libc = "^0.2.17"
1819
log = "^0.3.8"
1920
ref_slice = "^1.1.0"

src/bin/itmdump.rs

Lines changed: 91 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,51 @@ extern crate clap;
66
extern crate env_logger;
77
#[macro_use]
88
extern crate error_chain;
9+
extern crate heapless;
910
extern crate libc;
1011
#[macro_use]
1112
extern crate log;
1213
extern crate ref_slice;
1314

1415

1516
use clap::{Arg, App, ArgMatches};
17+
use heapless::Vec as HVec;
1618
use log::{LogRecord, LogLevelFilter};
17-
use ref_slice::ref_slice_mut;
1819
use std::fs::File;
1920
use std::io::{Read, Write};
2021
use std::time::Duration;
2122
use std::{env, io, process, thread};
2223

23-
use errors::*;
24+
use errors::{Error, ErrorKind, Result, ResultExt};
2425

2526
mod errors {
26-
error_chain!();
27+
error_chain! {
28+
foreign_links {
29+
Io(::std::io::Error);
30+
}
31+
32+
errors {
33+
UnknownHeader(b: u8) {
34+
description("unknown header byte"),
35+
display("unknown header byte: {:x}", b),
36+
}
37+
}
38+
}
39+
}
40+
41+
pub const MAX_PAYLOAD_SIZE: usize = 4;
42+
43+
// TODO: Probably add a .kind field and Kind enum when we need to handle more
44+
// kinds of packets.
45+
struct Packet {
46+
// The header byte received for this packet.
47+
pub header: u8,
48+
49+
/// Data in this packet.
50+
pub payload: HVec<u8, [u8; MAX_PAYLOAD_SIZE]>,
51+
52+
/// Stimuls port this packet was sent from.
53+
pub port: u8,
2754
}
2855

2956
fn main() {
@@ -96,7 +123,7 @@ fn run() -> Result<()> {
96123
}))
97124
.get_matches();
98125

99-
let stim_port = matches.value_of("port")
126+
let port = matches.value_of("port")
100127
.unwrap() // We supplied a default value
101128
.parse::<u8>()
102129
.expect("Arg validator should ensure this parses");
@@ -108,60 +135,40 @@ fn run() -> Result<()> {
108135
let stdout = io::stdout();
109136
let mut stdout = stdout.lock();
110137
loop {
111-
let mut header = 0;
112-
113-
if let Err(e) = (|| {
114-
try!(stream.read_exact(ref_slice_mut(&mut header)));
115-
let port = header >> 3;
116-
117-
// Ignore packets not from the chosen stimulus port
118-
if port != stim_port {
119-
return Ok(());
120-
}
121-
122-
match header & 0b111 {
123-
0b01 => {
124-
let mut payload = 0;
125-
try!(stream.read_exact(ref_slice_mut(&mut payload)));
126-
stdout.write_all(&[payload])
127-
}
128-
0b10 => {
129-
let mut payload = [0; 2];
130-
try!(stream.read_exact(&mut payload));
131-
stdout.write_all(&payload)
132-
}
133-
0b11 => {
134-
let mut payload = [0; 4];
135-
try!(stream.read_exact(&mut payload));
136-
stdout.write_all(&payload)
137-
}
138-
_ => {
139-
// We don't know this header type, skip.
140-
debug!("Unhandled header type = {:x}", header);
141-
Ok(())
138+
let p = read_packet(&mut stream);
139+
match p {
140+
Ok(p) => {
141+
if p.port == port {
142+
stdout.write_all(&p.payload)?;
142143
}
143144
}
144-
})() {
145-
// Error caught in main loop as `e`.
146-
if e.kind() == io::ErrorKind::UnexpectedEof {
145+
Err(e @ Error(ErrorKind::UnknownHeader(_), _)) => {
146+
// We don't know this header type; warn and continue.
147+
debug!("{}", e);
148+
},
149+
Err(Error(ErrorKind::Io(ref e), _))
150+
if e.kind() == io::ErrorKind::UnexpectedEof => {
147151
if follow {
148-
// TODO: There's a bug here where we can lose data.
149-
// UnexpectedEof is returned when read_exact() encounters EOF
150-
// before it fills its buffer, but in that case it may have
151-
// already read _some_ data, which we discard here.
152+
// TODO: There's a bug here where we can lose
153+
// data. UnexpectedEof is returned when
154+
// read_exact() encounters EOF before it fills its
155+
// buffer, but in that case it may have already
156+
// read _some_ data, which we discard here.
152157
//
153-
// We could buffer input until we can read a full packet,
154-
// or turn parsing into a state machine.
158+
// Instead we could buffer input until we can read
159+
// a full packet, or turn parsing into a state
160+
// machine.
155161
thread::sleep(Duration::from_millis(100));
156162
} else {
157163
// !follow and EOF. Exit.
158164
return Ok(())
159165
}
160-
} else {
161-
error!("{}", e);
162-
}
166+
},
167+
Err(e) => return Err(e),
163168
}
164-
}
169+
} // end of read loop
170+
171+
// Unreachable.
165172
}
166173

167174
fn open_read<'a>(matches: &ArgMatches) -> Result<impl io::Read + 'a> {
@@ -177,3 +184,39 @@ fn open_read<'a>(matches: &ArgMatches) -> Result<impl io::Read + 'a> {
177184
None => Box::new(io::stdin()) as Box<io::Read + 'static>,
178185
})
179186
}
187+
188+
fn read_packet(input: &mut Read) -> Result<Packet> {
189+
let mut header = [0; 1];
190+
input.read_exact(&mut header)?;
191+
let header = header[0];
192+
let mut packet = Packet {
193+
header: header,
194+
payload: HVec::new(),
195+
port: header >> 3,
196+
};
197+
match header & 0b111 {
198+
0b01|0b10|0b11 => {
199+
// Data packet.
200+
let payload_size =
201+
match header & 0b11 {
202+
0b01 => 1,
203+
0b10 => 2,
204+
0b11 => 4,
205+
_ => return Err(Error::from(
206+
ErrorKind::UnknownHeader(header))),
207+
};
208+
// TODO: payload.resize_default(), would be nice.
209+
for _ in 0..payload_size {
210+
packet.payload.push(0)
211+
.expect("payload_size <= packet.payload.capacity");
212+
}
213+
input.read_exact(&mut *packet.payload)?;
214+
Ok(packet)
215+
},
216+
_ => {
217+
return Err(Error::from(ErrorKind::UnknownHeader(header)));
218+
}
219+
}
220+
}
221+
222+
// TODO: Add parse tests.

0 commit comments

Comments
 (0)