|
@@ -0,0 +1,80 @@
|
|
|
+use comm;
|
|
|
+use comm::Channel;
|
|
|
+use std::fs::File;
|
|
|
+use std::io::prelude::*;
|
|
|
+use std::io;
|
|
|
+use std::thread;
|
|
|
+
|
|
|
+struct StatFiles {
|
|
|
+ rx: File,
|
|
|
+ tx: File
|
|
|
+}
|
|
|
+
|
|
|
+struct Stats {
|
|
|
+ rx: u32,
|
|
|
+ tx: u32
|
|
|
+}
|
|
|
+
|
|
|
+pub fn netspeed(tx: &Channel) {
|
|
|
+ let devices = [ "wlp2s0b1" ];
|
|
|
+ let mut files : Vec<StatFiles> = devices.iter()
|
|
|
+ .flat_map(|dev| open_stats(&dev).ok())
|
|
|
+ .collect();
|
|
|
+
|
|
|
+ let mut prev_stats : Option<Stats> = None;
|
|
|
+ loop {
|
|
|
+ let stats = files
|
|
|
+ .iter_mut()
|
|
|
+ .flat_map(|file| read_stats(file).ok())
|
|
|
+ .fold(Stats { rx: 0, tx: 0 }, |acc, elem| Stats {
|
|
|
+ rx: acc.rx + elem.rx,
|
|
|
+ tx: acc.tx + elem.tx
|
|
|
+ });
|
|
|
+ let output = match prev_stats {
|
|
|
+ Some(pstats) => {
|
|
|
+ let rx = format_bytes(stats.rx - pstats.rx);
|
|
|
+ let tx = format_bytes(stats.tx - pstats.tx);
|
|
|
+ format!("{}↓ {}↑", rx, tx)
|
|
|
+ },
|
|
|
+ None => "?".to_string()
|
|
|
+ };
|
|
|
+ prev_stats = Some(stats);
|
|
|
+ comm::send(tx, "netspeed", &output);
|
|
|
+ thread::sleep_ms(1000);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+fn format_bytes(bytes: u32) -> String {
|
|
|
+ let kib = bytes >> 10;
|
|
|
+ if kib > 1024 {
|
|
|
+ format!("{:.*} M", 1, (kib as f32) / 1024.0)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ format!("{} K", kib)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+fn open_stats(device: &str) -> Result<StatFiles, io::Error> {
|
|
|
+ let path = format!("/sys/class/net/{}/statistics", device);
|
|
|
+ let rx_file = try!(File::open(format!("{}/rx_bytes", path)));
|
|
|
+ let tx_file = try!(File::open(format!("{}/tx_bytes", path)));
|
|
|
+ Ok(StatFiles {
|
|
|
+ rx: rx_file,
|
|
|
+ tx: tx_file
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+fn read_stats(files: &mut StatFiles) -> Result<Stats, io::Error> {
|
|
|
+ Ok(Stats {
|
|
|
+ rx: read_bytes(&mut files.rx),
|
|
|
+ tx: read_bytes(&mut files.tx)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+fn read_bytes(f: &mut File) -> u32 {
|
|
|
+ let mut s = String::new();
|
|
|
+ assert!(f.read_to_string(&mut s).is_ok());
|
|
|
+ let i : u32 = s.trim().parse().unwrap();
|
|
|
+ assert!(f.seek(io::SeekFrom::Start(0)).is_ok());
|
|
|
+ i
|
|
|
+}
|