mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-06-18 02:19:44 -07:00
GPS feature webapp side: GPS mode selector, fixed mode lat/lon, API endpoint. Merging with Wifi client and webdav features
This commit is contained in:
committed by
Will Greenberg
parent
ac33ebaf53
commit
c107314194
@@ -36,6 +36,12 @@ pub struct Config {
|
||||
pub min_space_to_start_recording_mb: u64,
|
||||
/// Minimum disk space required to continue a recording
|
||||
pub min_space_to_continue_recording_mb: u64,
|
||||
/// GPS mode: 0=Disabled, 1=Fixed coordinates, 2=API endpoint
|
||||
pub gps_mode: u8,
|
||||
/// Fixed latitude used when gps_mode=1
|
||||
pub gps_fixed_latitude: Option<f64>,
|
||||
/// Fixed longitude used when gps_mode=1
|
||||
pub gps_fixed_longitude: Option<f64>,
|
||||
/// Wifi client SSID
|
||||
pub wifi_ssid: Option<String>,
|
||||
/// Wifi client password
|
||||
@@ -100,6 +106,9 @@ impl Default for Config {
|
||||
enabled_notifications: vec![NotificationType::Warning, NotificationType::LowBattery],
|
||||
min_space_to_start_recording_mb: 1,
|
||||
min_space_to_continue_recording_mb: 1,
|
||||
gps_mode: 0,
|
||||
gps_fixed_latitude: None,
|
||||
gps_fixed_longitude: None,
|
||||
wifi_ssid: None,
|
||||
wifi_password: None,
|
||||
wifi_security: None,
|
||||
@@ -153,6 +162,49 @@ fn resolve_bin(name: &str) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn wifi_config(&self) -> wifi_station::WifiConfig {
|
||||
let (wpa_bin, hostapd_conf, ctrl_interface) = match self.device {
|
||||
Device::Tmobile | Device::Wingtech => (
|
||||
Some("/usr/sbin/wpa_supplicant".into()),
|
||||
Some("/data/configs/hostapd.conf".into()),
|
||||
None,
|
||||
),
|
||||
Device::Uz801 => (
|
||||
Some("/system/bin/wpa_supplicant".into()),
|
||||
Some("/data/misc/wifi/hostapd.conf".into()),
|
||||
Some("/data/misc/wifi/sockets".into()),
|
||||
),
|
||||
_ => (None, None, None),
|
||||
};
|
||||
wifi_station::WifiConfig {
|
||||
wifi_enabled: self.wifi_enabled,
|
||||
dns_servers: self.dns_servers.clone(),
|
||||
wifi_ssid: self.wifi_ssid.clone(),
|
||||
wifi_password: self.wifi_password.clone(),
|
||||
security_type: self.wifi_security,
|
||||
wpa_supplicant_bin: wpa_bin.or_else(|| resolve_bin("wpa_supplicant")),
|
||||
hostapd_conf,
|
||||
ctrl_interface,
|
||||
udhcpc_hook_path: Some("/data/rayhunter/udhcpc-hook.sh".into()),
|
||||
dhcp_lease_path: Some("/data/rayhunter/dhcp_lease".into()),
|
||||
wpa_conf_path: Some("/data/rayhunter/wpa_sta.conf".into()),
|
||||
iw_bin: resolve_bin("iw"),
|
||||
udhcpc_bin: resolve_bin("udhcpc"),
|
||||
crash_log_dir: Some("/data/rayhunter/crash-logs".into()),
|
||||
wakelock_name: Some("rayhunter".into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_bin(name: &str) -> Option<String> {
|
||||
let local = format!("/data/rayhunter/bin/{name}");
|
||||
if std::path::Path::new(&local).exists() {
|
||||
return Some(local);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub async fn parse_config<P>(path: P) -> Result<Config, RayhunterError>
|
||||
where
|
||||
P: AsRef<std::path::Path>,
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
use axum::Json;
|
||||
use axum::extract::State;
|
||||
use axum::http::StatusCode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::server::ServerState;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct GpsData {
|
||||
pub latitude: f64,
|
||||
pub longitude: f64,
|
||||
pub timestamp: String,
|
||||
}
|
||||
|
||||
pub async fn post_gps(
|
||||
State(state): State<Arc<ServerState>>,
|
||||
Json(gps_data): Json<GpsData>,
|
||||
) -> Result<StatusCode, (StatusCode, String)> {
|
||||
if state.config.gps_mode != 2 {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"GPS API endpoint is disabled. Set gps_mode to 2 in configuration.".to_string(),
|
||||
));
|
||||
}
|
||||
let mut gps = state.gps_state.write().await;
|
||||
*gps = Some(gps_data);
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
||||
pub async fn get_gps(
|
||||
State(state): State<Arc<ServerState>>,
|
||||
) -> Result<Json<GpsData>, StatusCode> {
|
||||
let gps = state.gps_state.read().await;
|
||||
match gps.as_ref() {
|
||||
Some(data) => Ok(Json(data.clone())),
|
||||
None => Err(StatusCode::NOT_FOUND),
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ pub mod crypto_provider;
|
||||
pub mod diag;
|
||||
pub mod display;
|
||||
pub mod error;
|
||||
pub mod gps;
|
||||
pub mod key_input;
|
||||
pub mod notifications;
|
||||
pub mod pcap;
|
||||
|
||||
@@ -5,6 +5,7 @@ mod crypto_provider;
|
||||
mod diag;
|
||||
mod display;
|
||||
mod error;
|
||||
mod gps;
|
||||
mod key_input;
|
||||
mod notifications;
|
||||
mod pcap;
|
||||
@@ -23,6 +24,7 @@ use crate::error::RayhunterError;
|
||||
use crate::notifications::{NotificationService, run_notification_worker};
|
||||
use crate::pcap::get_pcap;
|
||||
use crate::qmdl_store::RecordingStore;
|
||||
use crate::gps::{get_gps, post_gps};
|
||||
use crate::server::{
|
||||
ServerState, debug_set_display_state, get_config, get_qmdl, get_time, get_wifi_status, get_zip,
|
||||
scan_wifi, serve_static, set_config, set_time_offset, test_notification,
|
||||
@@ -78,6 +80,8 @@ fn get_router() -> AppRouter {
|
||||
.route("/api/time", get(get_time))
|
||||
.route("/api/time-offset", post(set_time_offset))
|
||||
.route("/api/debug/display-state", post(debug_set_display_state))
|
||||
.route("/api/gps", get(get_gps))
|
||||
.route("/api/gps", post(post_gps))
|
||||
.route("/", get(|| async { Redirect::permanent("/index.html") }))
|
||||
.route("/{*path}", get(serve_static))
|
||||
}
|
||||
@@ -296,6 +300,18 @@ async fn run_with_config(
|
||||
config.webdav.clone().into(),
|
||||
);
|
||||
}
|
||||
let initial_gps = if config.gps_mode == 1 {
|
||||
match (config.gps_fixed_latitude, config.gps_fixed_longitude) {
|
||||
(Some(lat), Some(lon)) => Some(gps::GpsData {
|
||||
latitude: lat,
|
||||
longitude: lon,
|
||||
timestamp: "fixed".to_string(),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let state = Arc::new(ServerState {
|
||||
config_path: args.config_path.clone(),
|
||||
@@ -308,6 +324,7 @@ async fn run_with_config(
|
||||
ui_update_sender: Some(ui_update_tx),
|
||||
wifi_status,
|
||||
wifi_scan_lock: tokio::sync::Mutex::new(()),
|
||||
gps_state: Arc::new(tokio::sync::RwLock::new(initial_gps)),
|
||||
});
|
||||
run_server(&task_tracker, state, shutdown_token.clone()).await;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ use crate::config::Config;
|
||||
use crate::diag::DiagDeviceCtrlMessage;
|
||||
use crate::display::DisplayState;
|
||||
use crate::notifications::DEFAULT_NOTIFICATION_TIMEOUT;
|
||||
use crate::gps::GpsData;
|
||||
use crate::pcap::generate_pcap_data;
|
||||
use crate::qmdl_store::RecordingStore;
|
||||
|
||||
@@ -40,6 +41,7 @@ pub struct ServerState {
|
||||
pub ui_update_sender: Option<Sender<DisplayState>>,
|
||||
pub wifi_status: Arc<RwLock<wifi_station::WifiStatus>>,
|
||||
pub wifi_scan_lock: tokio::sync::Mutex<()>,
|
||||
pub gps_state: Arc<RwLock<Option<GpsData>>>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "apidocs", utoipa::path(
|
||||
@@ -566,6 +568,7 @@ mod tests {
|
||||
ui_update_sender: None,
|
||||
wifi_status: Arc::new(RwLock::new(wifi_station::WifiStatus::default())),
|
||||
wifi_scan_lock: tokio::sync::Mutex::new(()),
|
||||
gps_state: Arc::new(RwLock::new(None)),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user