From a696a05595303affa0616b892c340843d146eb38 Mon Sep 17 00:00:00 2001 From: Mika Date: Sun, 13 Oct 2024 20:29:05 +0200 Subject: [PATCH] implement mac address stuff --- Cargo.lock | 17 +++++ crates/backend/Cargo.toml | 1 + crates/backend/src/controller/node.rs | 90 ++++++++++++++++++++------- 3 files changed, 84 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8424ce..5cbe2bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -546,6 +546,7 @@ dependencies = [ "chrono", "dotenvy", "entity", + "eui48", "futures", "jsonwebtoken", "sea-orm", @@ -1111,6 +1112,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "eui48" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887418ac5e8d57c2e66e04bdc2fe15f9a5407be20b54a82c86bd0e368b709701" +dependencies = [ + "regex", + "rustc-serialize", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -2316,6 +2327,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-serialize" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" + [[package]] name = "rustc_version" version = "0.4.1" diff --git a/crates/backend/Cargo.toml b/crates/backend/Cargo.toml index acc9f14..37a16b3 100644 --- a/crates/backend/Cargo.toml +++ b/crates/backend/Cargo.toml @@ -19,3 +19,4 @@ dotenvy = "*" jsonwebtoken = "*" futures = "*" chrono = "*" +eui48 = "*" diff --git a/crates/backend/src/controller/node.rs b/crates/backend/src/controller/node.rs index f837d4f..eb93a0d 100644 --- a/crates/backend/src/controller/node.rs +++ b/crates/backend/src/controller/node.rs @@ -11,7 +11,7 @@ use uuid::Uuid; #[derive(Serialize)] struct NodeWithSensorData { - node: node::Model, + node: NodeWithMac, sensor_data: Vec, } @@ -20,29 +20,65 @@ pub struct CreateGroupWithoutId { name: String, } -#[derive(Deserialize)] -struct CreateNodeRequest { - id: u64, +#[derive(Deserialize, Serialize)] +pub struct NodeWithMac { + mac: String, group: uuid::Uuid, } +impl From for NodeWithMac { + fn from(value: node::Model) -> Self { + let mac_id_bytes = value.id.to_be_bytes(); + let mut mac_bytes: [u8; 6] = [0; 6]; + mac_bytes.copy_from_slice(&mac_id_bytes[2..]); + let mac = eui48::MacAddress::new(mac_bytes).to_string(eui48::MacAddressFormat::Canonical); + + Self { + mac, + group: value.group, + } + } +} + +impl TryInto for NodeWithMac { + type Error = eui48::ParseError; + + fn try_into(self) -> Result { + let mac = eui48::MacAddress::parse_str(&self.mac)?; + let mac_bytes = mac.to_array(); + let mut mac_id_bytes: [u8; 8] = [0; 8]; + mac_id_bytes[2..].copy_from_slice(&mac_bytes); + let mac_id = i64::from_be_bytes(mac_id_bytes); + Ok(node::Model { + id: mac_id, + group: self.group, + }) + } +} + #[derive(Serialize)] struct GroupWithNode { #[serde(flatten)] group: node_group::Model, - node: Vec, + node: Vec, } pub async fn get_nodes(state: web::Data) -> actix_web::Result { let db = &state.db; - let result = node_group::Entity::find() + let result: Vec = node_group::Entity::find() .find_with_related(entity::prelude::Node) .all(db) .await .map_err(ErrorInternalServerError)? .into_iter() - .map(|(group, node)| GroupWithNode { group, node }) + .map(|(group, nodes)| { + let nodes = nodes + .into_iter() + .map(|n| n.into()) + .collect::>(); + GroupWithNode { group, node: nodes } + }) .collect::>(); Ok(web::Json(result)) @@ -61,15 +97,17 @@ pub async fn get_data(state: web::Data) -> actix_web::Result = Vec::new(); for node in nodes { - let node_id = node.id.clone(); let sensor_data = sensor_data::Entity::find() - .filter(sensor_data::Column::NodeId.eq(node_id)) + .filter(sensor_data::Column::NodeId.eq(node.id)) .filter(sensor_data::Column::Timestamp.gt(one_hour_ago)) .all(db) .await .map_err(ErrorInternalServerError)?; - result.push(NodeWithSensorData { node, sensor_data }); + result.push(NodeWithSensorData { + node: node.into(), + sensor_data, + }); } Ok(web::Json(result)) @@ -95,16 +133,28 @@ pub async fn create_group( pub async fn create_node( state: web::Data, - node_request: web::Json, + node_request: web::Json, ) -> actix_web::Result { let db = &state.db; - let node = node_request.into_inner(); + let node: NodeWithMac = node_request.into_inner(); - let node = entity::node::ActiveModel { - id: ActiveValue::Set(node.id), - group: ActiveValue::Set(node_request.group), - }; + println!("Checking group ID: {:?}", node.group); + + let group_exists = entity::node_group::Entity::find_by_id(node.group) + .one(db) + .await + .map_err(ErrorInternalServerError)? + .is_some(); + + if !group_exists { + return Err(ErrorInternalServerError("Group ID does not exist")); + } + + let node: node::Model = node + .try_into() + .map_err(|_| ErrorBadRequest("Invalid Mac Address"))?; + let node = node.into_active_model(); let result = node.insert(db).await.map_err(ErrorInternalServerError)?; @@ -128,11 +178,3 @@ pub async fn delete_node( Ok(HttpResponse::Ok().finish()) } */ - -fn mac_to_i32(mac: &str) -> Result { - // Remove non-hexadecimal characters - let sanitized_mac: String = mac.chars().filter(|c| c.is_digit(16)).collect(); - - // Parse the sanitized string as a hexadecimal number - i32::from_str_radix(&sanitized_mac, 16) -}