Skip to content

Commit a3f85a8

Browse files
committed
tio-tool: improvements to logging and dumping
Allow to dump and log subtrees. log-csv can now pick a specific stream/sensor to output, and can be supplied metadata from a file
1 parent 58740d3 commit a3f85a8

File tree

2 files changed

+90
-50
lines changed

2 files changed

+90
-50
lines changed

twinleaf-tools/src/bin/tio-tool.rs

Lines changed: 88 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -294,49 +294,31 @@ fn rpc_dump(args: &[String]) -> Result<(), ()> {
294294
Ok(())
295295
}
296296

297-
/*
298-
fn read_capture(args: &[String]) -> Result<(),()> {
299-
let prefix = &args[0];
300-
let data_type = &args[1];
301-
let trigger = format!("{}.trigger", prefix.clone());
302-
let block = format!("{}.block", prefix.clone());
303-
let size = format! {"{}.size", prefix.clone()};
304-
let blocksize = format! {"{}.blocksize", prefix.clone()};
305-
306-
let _ = rpc(&[trigger]);
307-
308-
let mut num_blocks: f32 = 0.0;
309-
if let Ok(sizenum) = rpc(&[size]) {
310-
let size32: f32 = sizenum.parse().expect();
311-
if let Ok(blocknum) = rpc(&[blocksize]) {
312-
let blocksize32: f32 = blocknum.parse().expect();
313-
let block_len = (size32 / blocksize32).floor();
314-
num_blocks = block_len;
315-
}
316-
}
317-
for i in 0..(num_blocks as i32 - 1) {
318-
let mut command = vec![
319-
"rpc".to_string(),
320-
"-t".to_string(),
321-
"-T".to_string(),
322-
"string".to_string(),
323-
];
324-
command.insert(1, block.clone());
325-
command.insert(2, i.to_string());
326-
command.insert(4, data_type.clone());
327-
328-
_ = rpc(&command[1..]);
329-
}
330-
Ok(())
331-
}
332-
*/
333297
fn dump(args: &[String]) -> Result<(), ()> {
334-
let opts = tio_opts();
335-
let (_matches, root, _route) = tio_parseopts(&opts, args);
298+
let mut opts = tio_opts();
299+
opts.optopt(
300+
"d",
301+
"depth",
302+
"Dump depth (default: dump everything)",
303+
"max-depth",
304+
);
305+
let (matches, root, route) = tio_parseopts(&opts, args);
306+
let depth = matches
307+
.opt_str("d")
308+
.unwrap_or(format!("{}", tio::proto::TIO_PACKET_MAX_ROUTING_SIZE))
309+
.parse::<usize>()
310+
.map_err(|e| {
311+
eprintln!("Failed to parse depth: {:?}", e);
312+
})?;
336313

337314
let proxy = proxy::Interface::new(&root);
315+
let port = proxy
316+
.new_port(None, route, depth, true, true)
317+
.map_err(|e| {
318+
eprintln!("Failed to initialize proxy port: {:?}", e);
319+
})?;
338320

339-
for pkt in proxy.tree_full().unwrap().iter() {
321+
for pkt in port.iter() {
340322
println!("{:?}", pkt);
341323
}
342324
Ok(())
@@ -414,7 +396,20 @@ fn log(args: &[String]) -> Result<(), ()> {
414396
"path",
415397
);
416398
opts.optflag("u", "", "unbuffered output");
399+
opts.optopt(
400+
"d",
401+
"depth",
402+
"Dump depth (default: dump everything)",
403+
"max-depth",
404+
);
417405
let (matches, root, route) = tio_parseopts(&opts, args);
406+
let depth = matches
407+
.opt_str("d")
408+
.unwrap_or(format!("{}", tio::proto::TIO_PACKET_MAX_ROUTING_SIZE))
409+
.parse::<usize>()
410+
.map_err(|e| {
411+
eprintln!("Failed to parse depth: {:?}", e);
412+
})?;
418413
if matches.free.len() != 0 {
419414
print!("{}", opts.usage("Unexpected argument"));
420415
return Err(());
@@ -427,11 +422,16 @@ fn log(args: &[String]) -> Result<(), ()> {
427422
};
428423

429424
let proxy = proxy::Interface::new(&root);
425+
let port = proxy
426+
.new_port(None, route, depth, true, true)
427+
.map_err(|e| {
428+
eprintln!("Failed to initialize proxy port: {:?}", e);
429+
})?;
430430

431431
let mut file = File::create(output_path).unwrap();
432432
let sync = matches.opt_present("u");
433433

434-
for pkt in proxy.device_full(route).unwrap().iter() {
434+
for pkt in port.iter() {
435435
let raw = pkt.serialize().unwrap();
436436
file.write_all(&raw).unwrap();
437437
if sync {
@@ -516,26 +516,66 @@ fn log_data_dump(args: &[String]) -> Result<(), ()> {
516516
}
517517

518518
fn log_csv(args: &[String]) -> Result<(), ()> {
519-
let mut parser = DeviceDataParser::new(args.len() > 1);
520-
let id: u8 = args[1].parse().unwrap();
521-
let output_name = args.get(3).unwrap_or(&args[2]);
522-
523-
let s = output_name.replace("csv", "");
524-
let path = format!("{}{}.csv", s, &args[1]).to_string();
519+
let mut opts = getopts::Options::new();
520+
opts.optopt(
521+
"s",
522+
"",
523+
"sensor path in the sensor tree (default /)",
524+
"path",
525+
);
526+
opts.optopt("m", "", "metadata file (if separate)", "path");
527+
opts.optopt("o", "", "output file prefix", "prefix");
528+
let matches = opts.parse(args).map_err(|e| {
529+
eprintln!("Invalid invocation: {:?}", e);
530+
})?;
531+
if matches.free.len() < 3 {
532+
eprintln!("Invalid invocation: missing log file");
533+
return Err(());
534+
}
535+
let route = if let Some(path) = matches.opt_str("s") {
536+
DeviceRoute::from_str(&path).unwrap()
537+
} else {
538+
DeviceRoute::root()
539+
};
540+
let mut parser = if let Some(path) = matches.opt_str("m") {
541+
let mut parser = DeviceDataParser::new(true);
542+
let mut meta: &[u8] = &std::fs::read(path).unwrap();
543+
while meta.len() > 0 {
544+
let (pkt, len) = tio::Packet::deserialize(meta).unwrap();
545+
meta = &meta[len..];
546+
for _ in parser.process_packet(&pkt) {}
547+
}
548+
parser
549+
} else {
550+
DeviceDataParser::new(matches.free.len() > 3)
551+
};
552+
let id: u8 = matches.free[1].parse().unwrap();
553+
let output_path = format!(
554+
"{}.{}.csv",
555+
if let Some(path) = matches.opt_str("o") {
556+
path
557+
} else {
558+
matches.free[2].clone()
559+
},
560+
id
561+
);
525562

526563
let mut file = OpenOptions::new()
527564
.append(true)
528565
.create(true)
529-
.open(path)
566+
.open(output_path)
530567
.or(Err(()))?;
531568

532569
let mut header_written: bool = false;
533570

534-
for path in &args[2..] {
571+
for path in &matches.free[2..] {
535572
let mut rest: &[u8] = &std::fs::read(path).unwrap();
536573
while rest.len() > 0 {
537574
let (pkt, len) = tio::Packet::deserialize(rest).unwrap();
538575
rest = &rest[len..];
576+
if pkt.routing != route {
577+
continue;
578+
}
539579
for sample in parser.process_packet(&pkt) {
540580
if sample.stream.stream_id != id {
541581
continue;

twinleaf/src/tio/proto.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ struct TioPktHdr {
147147
payload_size: u16,
148148
}
149149

150-
static TIO_PACKET_HEADER_SIZE: usize = 4;
151-
static TIO_PACKET_MAX_ROUTING_SIZE: usize = 8;
150+
pub static TIO_PACKET_HEADER_SIZE: usize = 4;
151+
pub static TIO_PACKET_MAX_ROUTING_SIZE: usize = 8;
152152
pub static TIO_PACKET_MAX_TOTAL_SIZE: usize = 512;
153153
static TIO_PACKET_MAX_PAYLOAD_SIZE: usize =
154154
TIO_PACKET_MAX_TOTAL_SIZE - TIO_PACKET_HEADER_SIZE - TIO_PACKET_MAX_ROUTING_SIZE;

0 commit comments

Comments
 (0)