summaryrefslogtreecommitdiff
path: root/src/routes/start.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes/start.rs')
-rw-r--r--src/routes/start.rs106
1 files changed, 98 insertions, 8 deletions
diff --git a/src/routes/start.rs b/src/routes/start.rs
index ef6e8f2..ff3d1be 100644
--- a/src/routes/start.rs
+++ b/src/routes/start.rs
@@ -2,27 +2,28 @@ use crate::db::Device;
2use crate::error::Error; 2use crate::error::Error;
3use crate::services::ping::Value as PingValue; 3use crate::services::ping::Value as PingValue;
4use crate::wol::{create_buffer, send_packet}; 4use crate::wol::{create_buffer, send_packet};
5use axum::extract::State; 5use axum::extract::{Path, State};
6use axum::Json; 6use axum::Json;
7use serde::{Deserialize, Serialize}; 7use serde::{Deserialize, Serialize};
8use serde_json::{json, Value}; 8use serde_json::{json, Value};
9use utoipa::ToSchema;
10use std::sync::Arc; 9use std::sync::Arc;
11use tracing::{debug, info}; 10use tracing::{debug, info};
11use utoipa::ToSchema;
12use uuid::Uuid; 12use uuid::Uuid;
13 13
14#[utoipa::path( 14#[utoipa::path(
15 post, 15 post,
16 path = "/start", 16 path = "/start",
17 request_body = Payload, 17 request_body = PayloadOld,
18 responses( 18 responses(
19 (status = 200, description = "List matching todos by query", body = [Response]) 19 (status = 200, description = "DEP", body = [Response])
20 ), 20 ),
21 security(("api_key" = [])) 21 security((), ("api_key" = []))
22)] 22)]
23pub async fn start( 23#[deprecated]
24pub async fn start_payload(
24 State(state): State<Arc<crate::AppState>>, 25 State(state): State<Arc<crate::AppState>>,
25 Json(payload): Json<Payload>, 26 Json(payload): Json<PayloadOld>,
26) -> Result<Json<Value>, Error> { 27) -> Result<Json<Value>, Error> {
27 info!("POST request"); 28 info!("POST request");
28 let device = sqlx::query_as!( 29 let device = sqlx::query_as!(
@@ -59,6 +60,89 @@ pub async fn start(
59 }))) 60 })))
60} 61}
61 62
63#[utoipa::path(
64 post,
65 path = "/start/{id}",
66 request_body = Option<Payload>,
67 responses(
68 (status = 200, description = "start the device with the given id", body = [Response])
69 ),
70 params(
71 ("id" = String, Path, description = "device id")
72 ),
73 security((), ("api_key" = []))
74)]
75pub async fn post(
76 State(state): State<Arc<crate::AppState>>,
77 Path(id): Path<String>,
78 payload: Option<Json<Payload>>,
79) -> Result<Json<Value>, Error> {
80 send_wol(state, &id, payload).await
81}
82
83#[utoipa::path(
84 get,
85 path = "/start/{id}",
86 responses(
87 (status = 200, description = "start the device with the given id", body = [Response])
88 ),
89 params(
90 ("id" = String, Path, description = "device id")
91 ),
92 security((), ("api_key" = []))
93)]
94pub async fn get(
95 State(state): State<Arc<crate::AppState>>,
96 Path(id): Path<String>,
97) -> Result<Json<Value>, Error> {
98 send_wol(state, &id, None).await
99}
100
101async fn send_wol(
102 state: Arc<crate::AppState>,
103 id: &str,
104 payload: Option<Json<Payload>>,
105) -> Result<Json<Value>, Error> {
106 info!("Start request for {id}");
107 let device = sqlx::query_as!(
108 Device,
109 r#"
110 SELECT id, mac, broadcast_addr, ip, times
111 FROM devices
112 WHERE id = $1;
113 "#,
114 id
115 )
116 .fetch_one(&state.db)
117 .await?;
118
119 info!("starting {}", device.id);
120
121 let bind_addr = "0.0.0.0:0";
122
123 let _ = send_packet(
124 bind_addr,
125 &device.broadcast_addr,
126 &create_buffer(&device.mac.to_string())?,
127 )?;
128 let dev_id = device.id.clone();
129 let uuid = if let Some(pl) = payload {
130 if pl.ping.is_some_and(|ping| ping) {
131 Some(setup_ping(state, device))
132 } else {
133 None
134 }
135 } else {
136 None
137 };
138
139 Ok(Json(json!(Response {
140 id: dev_id,
141 boot: true,
142 uuid
143 })))
144}
145
62fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String { 146fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String {
63 let mut uuid: Option<String> = None; 147 let mut uuid: Option<String> = None;
64 for (key, value) in state.ping_map.clone() { 148 for (key, value) in state.ping_map.clone() {
@@ -99,11 +183,17 @@ fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String {
99} 183}
100 184
101#[derive(Deserialize, ToSchema)] 185#[derive(Deserialize, ToSchema)]
102pub struct Payload { 186#[deprecated]
187pub struct PayloadOld {
103 id: String, 188 id: String,
104 ping: Option<bool>, 189 ping: Option<bool>,
105} 190}
106 191
192#[derive(Deserialize, ToSchema)]
193pub struct Payload {
194 ping: Option<bool>,
195}
196
107#[derive(Serialize, ToSchema)] 197#[derive(Serialize, ToSchema)]
108pub struct Response { 198pub struct Response {
109 id: String, 199 id: String,