aboutsummaryrefslogtreecommitdiff
path: root/src/routes/start.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes/start.rs')
-rw-r--r--src/routes/start.rs138
1 files changed, 66 insertions, 72 deletions
diff --git a/src/routes/start.rs b/src/routes/start.rs
index ce95bf3..d4c0802 100644
--- a/src/routes/start.rs
+++ b/src/routes/start.rs
@@ -1,10 +1,8 @@
1use crate::auth::auth;
2use crate::db::Device; 1use crate::db::Device;
3use crate::error::Error; 2use crate::error::Error;
4use crate::services::ping::Value as PingValue; 3use crate::services::ping::Value as PingValue;
5use crate::wol::{create_buffer, send_packet}; 4use crate::wol::{create_buffer, send_packet};
6use axum::extract::State; 5use axum::extract::State;
7use axum::http::HeaderMap;
8use axum::Json; 6use axum::Json;
9use serde::{Deserialize, Serialize}; 7use serde::{Deserialize, Serialize};
10use serde_json::{json, Value}; 8use serde_json::{json, Value};
@@ -12,86 +10,82 @@ use std::sync::Arc;
12use tracing::{debug, info}; 10use tracing::{debug, info};
13use uuid::Uuid; 11use uuid::Uuid;
14 12
15#[axum_macros::debug_handler]
16pub async fn start( 13pub async fn start(
17 State(state): State<Arc<crate::AppState>>, 14 State(state): State<Arc<crate::AppState>>,
18 headers: HeaderMap,
19 Json(payload): Json<Payload>, 15 Json(payload): Json<Payload>,
20) -> Result<Json<Value>, Error> { 16) -> Result<Json<Value>, Error> {
21 info!("POST request"); 17 info!("POST request");
22 let secret = headers.get("authorization"); 18 let device = sqlx::query_as!(
23 let authorized = auth(&state.config, secret).map_err(Error::Auth)?; 19 Device,
24 if authorized { 20 r#"
25 let device = sqlx::query_as!( 21 SELECT id, mac, broadcast_addr, ip, times
26 Device, 22 FROM devices
27 r#" 23 WHERE id = $1;
28 SELECT id, mac, broadcast_addr, ip, times 24 "#,
29 FROM devices 25 payload.id
30 WHERE id = $1; 26 )
31 "#, 27 .fetch_one(&state.db)
32 payload.id 28 .await?;
33 )
34 .fetch_one(&state.db)
35 .await
36 .map_err(Error::DB)?;
37
38 info!("starting {}", device.id);
39
40 let bind_addr = "0.0.0.0:0";
41 29
42 let _ = send_packet( 30 info!("starting {}", device.id);
43 &bind_addr.parse().map_err(Error::IpParse)?,
44 &device.broadcast_addr.parse().map_err(Error::IpParse)?,
45 &create_buffer(&device.mac)?,
46 )?;
47 let dev_id = device.id.clone();
48 let uuid = if payload.ping.is_some_and(|ping| ping) {
49 let mut uuid: Option<String> = None;
50 for (key, value) in state.ping_map.clone() {
51 if value.ip == device.ip {
52 debug!("service already exists");
53 uuid = Some(key);
54 break;
55 }
56 }
57 let uuid_gen = match uuid {
58 Some(u) => u,
59 None => Uuid::new_v4().to_string(),
60 };
61 let uuid_genc = uuid_gen.clone();
62 31
63 tokio::spawn(async move { 32 let bind_addr = "0.0.0.0:0";
64 debug!("init ping service");
65 state.ping_map.insert(
66 uuid_gen.clone(),
67 PingValue {
68 ip: device.ip.clone(),
69 online: false,
70 },
71 );
72 33
73 crate::services::ping::spawn( 34 let _ = send_packet(
74 state.ping_send.clone(), 35 bind_addr,
75 &state.config, 36 &device.broadcast_addr,
76 device, 37 &create_buffer(&device.mac.to_string())?,
77 uuid_gen.clone(), 38 )?;
78 &state.ping_map, 39 let dev_id = device.id.clone();
79 &state.db, 40 let uuid = if payload.ping.is_some_and(|ping| ping) {
80 ) 41 Some(setup_ping(state, device))
81 .await;
82 });
83 Some(uuid_genc)
84 } else {
85 None
86 };
87 Ok(Json(json!(Response {
88 id: dev_id,
89 boot: true,
90 uuid
91 })))
92 } else { 42 } else {
93 Err(Error::Generic) 43 None
44 };
45 Ok(Json(json!(Response {
46 id: dev_id,
47 boot: true,
48 uuid
49 })))
50}
51
52fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String {
53 let mut uuid: Option<String> = None;
54 for (key, value) in state.ping_map.clone() {
55 if value.ip == device.ip {
56 debug!("service already exists");
57 uuid = Some(key);
58 break;
59 }
94 } 60 }
61 let uuid_gen = match uuid {
62 Some(u) => u,
63 None => Uuid::new_v4().to_string(),
64 };
65 let uuid_ret = uuid_gen.clone();
66
67 debug!("init ping service");
68 state.ping_map.insert(
69 uuid_gen.clone(),
70 PingValue {
71 ip: device.ip,
72 online: false,
73 },
74 );
75
76 tokio::spawn(async move {
77 crate::services::ping::spawn(
78 state.ping_send.clone(),
79 &state.config,
80 device,
81 uuid_gen,
82 &state.ping_map,
83 &state.db,
84 )
85 .await;
86 });
87
88 uuid_ret
95} 89}
96 90
97#[derive(Deserialize)] 91#[derive(Deserialize)]