diff options
Diffstat (limited to 'src/routes/start.rs')
-rw-r--r-- | src/routes/start.rs | 138 |
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 @@ | |||
1 | use crate::auth::auth; | ||
2 | use crate::db::Device; | 1 | use crate::db::Device; |
3 | use crate::error::Error; | 2 | use crate::error::Error; |
4 | use crate::services::ping::Value as PingValue; | 3 | use crate::services::ping::Value as PingValue; |
5 | use crate::wol::{create_buffer, send_packet}; | 4 | use crate::wol::{create_buffer, send_packet}; |
6 | use axum::extract::State; | 5 | use axum::extract::State; |
7 | use axum::http::HeaderMap; | ||
8 | use axum::Json; | 6 | use axum::Json; |
9 | use serde::{Deserialize, Serialize}; | 7 | use serde::{Deserialize, Serialize}; |
10 | use serde_json::{json, Value}; | 8 | use serde_json::{json, Value}; |
@@ -12,86 +10,82 @@ use std::sync::Arc; | |||
12 | use tracing::{debug, info}; | 10 | use tracing::{debug, info}; |
13 | use uuid::Uuid; | 11 | use uuid::Uuid; |
14 | 12 | ||
15 | #[axum_macros::debug_handler] | ||
16 | pub async fn start( | 13 | pub 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 | |||
52 | fn 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)] |