use crate::packet::identifier::Identifier; use crate::packet::{Packet, ToPacket}; use crate::packet::packet_data::PacketData; pub enum NodeManagement { Ping, RegisterNode { device_id: Identifier }, RemoveNode, RegisterProperty { property_name: String, data_type: u8, read_only: bool, }, RemoveProperty { property_name: String, }, Error { error_code: u8, metadata: [u8; 0xFFFF], }, } impl NodeManagement { fn get_command(&self) -> u8 { match self { NodeManagement::Ping => 0x00, NodeManagement::RegisterNode { .. } => 0x01, NodeManagement::RemoveNode => 0x02, NodeManagement::RegisterProperty { .. } => 0x03, NodeManagement::RemoveProperty { .. } => 0x04, NodeManagement::Error { .. } => 0x0E } } } impl Into for Packet { fn into(self) -> NodeManagement { match self { Packet::V1 { src, dest, packet_id, reply_to, command, data, } => match command { 0x00 => NodeManagement::Ping, 0x01 => NodeManagement::RegisterNode { device_id: src }, 0x02 => NodeManagement::RemoveNode, 0x03 => NodeManagement::RegisterProperty { property_name: String::from_utf8(data.get_data()[..32].to_vec()).unwrap(), data_type: data.get_data()[33], read_only: data.get_data()[34] != 0 }, 0x04 => NodeManagement::RemoveProperty { property_name: String::from_utf8(data.get_data()[..32].to_vec()).unwrap() }, 0x0E => NodeManagement::Error { error_code: data.get_data()[0], metadata: { let mut metadata = [0_u8; 0xFFFF]; let data_slice = data.get_data(); let metadata_length = u16::from_be_bytes([data_slice[1], data_slice[2]]) as usize; if metadata_length <= 0xFFFF { metadata[..metadata_length].copy_from_slice(&data_slice[3..(3 + metadata_length)]); } metadata } }, _ => unreachable!("Invalid command in Packet::V1"), }, } } } impl Into for NodeManagement { fn into(self) -> PacketData { match self { NodeManagement::Ping => PacketData::default(), NodeManagement::RegisterNode { device_id } => PacketData::new(Vec::from(device_id.bytes)), NodeManagement::RemoveNode => PacketData::default(), NodeManagement::RegisterProperty { property_name, data_type, read_only } => PacketData::new({ let mut vec = vec![]; vec.extend(property_name.into_bytes()); vec.push(data_type); vec.push(read_only as u8); vec }), NodeManagement::RemoveProperty { property_name } => PacketData::new(property_name.into_bytes()), NodeManagement::Error { error_code, metadata } => PacketData::new({ let mut vec = vec![]; vec.push(error_code); vec.extend_from_slice(metadata.as_ref()); vec }) } } } impl ToPacket for NodeManagement { fn to_v1_packet(self, src: Identifier, dest: Identifier, packet_id: Identifier, reply_to: Identifier) -> Packet { Packet::V1 { src, dest, packet_id, reply_to, command: self.get_command(), data: self.into() } } } #[allow(non_camel_case_types)] pub enum NodeManagementError { net_duplicate_packet, net_broken_packet, net_invalid_packet, errc_not_registered, errs_not_delivered, } impl NodeManagementError { pub fn error_code(&self) -> u8 { match self { NodeManagementError::net_duplicate_packet => 0x00, NodeManagementError::net_broken_packet => 0x01, NodeManagementError::net_invalid_packet => 0x02, NodeManagementError::errc_not_registered => 0x10, NodeManagementError::errs_not_delivered => 0x20 } } }