mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-05-01 18:00:00 -07:00
Expose severity to display
See https://github.com/EFForg/rayhunter/issues/334 Severity levels low, medium, high are now exposed to the UI in form of dotted, dashed and solid lines. The line on the UI represents the highest-so-far severity seen. Originally this was intended to be represented by Yellow/Orange/Red, but this would mean yet another divergence for colorblind mode. This is colorblind-friendly by default (I think...) As part of this, simplify EventType so that it becomes a flat "level" enum without nested variants. There is also a new debug endpoint that allows one to overwrite the display level directly for testing.
This commit is contained in:
committed by
Cooper Quintin
parent
6927da49b4
commit
781d11ed72
@@ -5,6 +5,7 @@ use std::time::Duration;
|
||||
|
||||
use crate::config;
|
||||
use crate::display::DisplayState;
|
||||
use rayhunter::analysis::analyzer::EventType;
|
||||
|
||||
use log::{error, info};
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
@@ -20,6 +21,13 @@ pub struct Dimensions {
|
||||
pub width: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum LinePattern {
|
||||
Solid,
|
||||
Dashed, // _ _ _ _
|
||||
Dotted, // . . . .
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Color {
|
||||
@@ -48,18 +56,36 @@ impl Color {
|
||||
}
|
||||
}
|
||||
|
||||
impl Color {
|
||||
fn from_state(state: DisplayState, colorblind_mode: bool) -> Self {
|
||||
match state {
|
||||
DisplayState::Paused => Color::White,
|
||||
DisplayState::Recording => {
|
||||
if colorblind_mode {
|
||||
Color::Blue
|
||||
} else {
|
||||
Color::Green
|
||||
}
|
||||
fn display_style_from_state(state: DisplayState, colorblind_mode: bool) -> (Color, LinePattern) {
|
||||
match state {
|
||||
DisplayState::Paused => (Color::White, LinePattern::Solid),
|
||||
DisplayState::Recording => {
|
||||
if colorblind_mode {
|
||||
(Color::Blue, LinePattern::Solid)
|
||||
} else {
|
||||
(Color::Green, LinePattern::Solid)
|
||||
}
|
||||
DisplayState::WarningDetected => Color::Red,
|
||||
}
|
||||
DisplayState::WarningDetected { event_type } => {
|
||||
let pattern = match event_type {
|
||||
EventType::Informational => LinePattern::Solid,
|
||||
EventType::Low => LinePattern::Dotted,
|
||||
EventType::Medium => LinePattern::Dashed,
|
||||
EventType::High => LinePattern::Solid,
|
||||
};
|
||||
|
||||
let color = match event_type {
|
||||
EventType::Informational => {
|
||||
if colorblind_mode {
|
||||
Color::Blue
|
||||
} else {
|
||||
Color::Green
|
||||
}
|
||||
}
|
||||
_ => Color::Red,
|
||||
};
|
||||
|
||||
(color, pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,11 +146,28 @@ pub trait GenericFramebuffer: Send + 'static {
|
||||
}
|
||||
|
||||
async fn draw_line(&mut self, color: Color, height: u32) {
|
||||
self.draw_patterned_line(color, height, LinePattern::Solid)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn draw_patterned_line(&mut self, color: Color, height: u32, pattern: LinePattern) {
|
||||
let width = self.dimensions().width;
|
||||
let px_num = height * width;
|
||||
let mut buffer = Vec::new();
|
||||
for _ in 0..px_num {
|
||||
buffer.push(color.rgb());
|
||||
|
||||
for _row in 0..height {
|
||||
for col in 0..width {
|
||||
let should_draw = match pattern {
|
||||
LinePattern::Solid => true,
|
||||
LinePattern::Dashed => (col / 4) % 2 == 0, // 4 pixels on, 4 pixels off
|
||||
LinePattern::Dotted => col % 4 == 0, // 1 pixel on, 3 pixels off
|
||||
};
|
||||
|
||||
if should_draw {
|
||||
buffer.push(color.rgb());
|
||||
} else {
|
||||
buffer.push((0, 0, 0)); // Black background
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.write_buffer(buffer).await
|
||||
@@ -145,7 +188,7 @@ pub fn update_ui(
|
||||
}
|
||||
|
||||
let colorblind_mode = config.colorblind_mode;
|
||||
let mut display_color = Color::from_state(DisplayState::Recording, colorblind_mode);
|
||||
let mut display_style = display_style_from_state(DisplayState::Recording, colorblind_mode);
|
||||
|
||||
task_tracker.spawn(async move {
|
||||
// this feels wrong, is there a more rusty way to do this?
|
||||
@@ -176,7 +219,7 @@ pub fn update_ui(
|
||||
}
|
||||
match ui_update_rx.try_recv() {
|
||||
Ok(state) => {
|
||||
display_color = Color::from_state(state, colorblind_mode);
|
||||
display_style = display_style_from_state(state, colorblind_mode);
|
||||
}
|
||||
Err(tokio::sync::mpsc::error::TryRecvError::Empty) => {}
|
||||
Err(e) => error!("error receiving framebuffer update message: {e}"),
|
||||
@@ -196,7 +239,8 @@ pub fn update_ui(
|
||||
// unknown value is used
|
||||
_ => {}
|
||||
};
|
||||
fb.draw_line(display_color, 2).await;
|
||||
let (color, pattern) = display_style;
|
||||
fb.draw_patterned_line(color, 2, pattern).await;
|
||||
tokio::time::sleep(Duration::from_millis(1000)).await;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use rayhunter::analysis::analyzer::EventType;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod generic_framebuffer;
|
||||
|
||||
pub mod headless;
|
||||
@@ -9,9 +12,15 @@ pub mod tplink_onebit;
|
||||
pub mod uz801;
|
||||
pub mod wingtech;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[derive(Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub enum DisplayState {
|
||||
/// We're recording but no warning has been found yet.
|
||||
Recording,
|
||||
/// We're not recording.
|
||||
Paused,
|
||||
WarningDetected,
|
||||
/// A non-informational event has been detected.
|
||||
///
|
||||
/// Note that EventType::Informational is never sent through this. If it is, it's the same as
|
||||
/// Recording
|
||||
WarningDetected { event_type: EventType },
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// Display module for Tmobile TMOHS1, blink LEDs on the front of the device.
|
||||
/// DisplayState::Recording => Signal LED slowly blinks blue.
|
||||
/// DisplayState::Paused => WiFi LED blinks white.
|
||||
/// DisplayState::WarningDetected => Signal LED slowly blinks red.
|
||||
/// DisplayState::WarningDetected { .. } => Signal LED slowly blinks red.
|
||||
use log::{error, info};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::oneshot;
|
||||
@@ -68,7 +68,7 @@ pub fn update_ui(
|
||||
stop_blinking(led!("signal_red")).await;
|
||||
start_blinking(led!("signal_blue")).await;
|
||||
}
|
||||
DisplayState::WarningDetected => {
|
||||
DisplayState::WarningDetected { .. } => {
|
||||
stop_blinking(led!("wlan_white")).await;
|
||||
stop_blinking(led!("signal_blue")).await;
|
||||
start_blinking(led!("signal_red")).await;
|
||||
|
||||
@@ -136,7 +136,7 @@ pub fn update_ui(
|
||||
match ui_update_rx.try_recv() {
|
||||
Ok(DisplayState::Paused) => pixels = STATUS_PAUSED,
|
||||
Ok(DisplayState::Recording) => pixels = STATUS_SMILING,
|
||||
Ok(DisplayState::WarningDetected) => pixels = STATUS_WARNING,
|
||||
Ok(DisplayState::WarningDetected { .. }) => pixels = STATUS_WARNING,
|
||||
Err(tokio::sync::mpsc::error::TryRecvError::Empty) => {}
|
||||
Err(e) => {
|
||||
error!("error receiving framebuffer update message: {e}");
|
||||
|
||||
@@ -73,7 +73,7 @@ pub fn update_ui(
|
||||
led_off(led!("wifi")).await;
|
||||
led_on(led!("green")).await;
|
||||
}
|
||||
DisplayState::WarningDetected => {
|
||||
DisplayState::WarningDetected { .. } => {
|
||||
led_off(led!("green")).await;
|
||||
led_off(led!("wifi")).await;
|
||||
led_on(led!("red")).await;
|
||||
|
||||
Reference in New Issue
Block a user