86 lines
2.9 KiB
Rust
86 lines
2.9 KiB
Rust
use std::io;
|
|
use crate::identifier::Identifier;
|
|
use crate::packet::raw_packet::RawPacket;
|
|
use crate::packet::{Packet, ToPacket};
|
|
use crate::packet::packet_data::PacketData;
|
|
|
|
pub mod vec;
|
|
pub mod errors;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub enum NodeManagementCommand {
|
|
Ping,
|
|
RegisterNode { device_id: Identifier },
|
|
RemoveNode,
|
|
AcknowledgePackets {
|
|
packet_ids: Vec<Identifier>
|
|
},
|
|
Error {
|
|
error_code: u8,
|
|
metadata: Vec<u8>,
|
|
},
|
|
}
|
|
|
|
impl NodeManagementCommand {
|
|
pub fn command(&self) -> u8 {
|
|
match self {
|
|
NodeManagementCommand::Ping => 0x00,
|
|
NodeManagementCommand::RegisterNode { .. } => 0x01,
|
|
NodeManagementCommand::RemoveNode => 0x02,
|
|
NodeManagementCommand::AcknowledgePackets { .. } => 0x0A,
|
|
NodeManagementCommand::Error { .. } => 0x0E,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ToPacket for NodeManagementCommand {
|
|
fn to_packet(self, src: Identifier, dest: Identifier, packet_id: Identifier, reply_to: Identifier) -> Packet {
|
|
Packet {
|
|
src, dest, packet_id, reply_to,
|
|
command: self.command(),
|
|
data: PacketData::NodeManagement(self.clone())
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<RawPacket> for NodeManagementCommand {
|
|
type Error = io::Error;
|
|
fn try_from(raw_packet: RawPacket) -> io::Result<Self> {
|
|
let build_invalid_input_err = |r: &str| {
|
|
Err(io::Error::new(io::ErrorKind::InvalidInput, r))
|
|
};
|
|
match raw_packet.command {
|
|
// ping
|
|
0x00 => Ok(NodeManagementCommand::Ping),
|
|
// register node
|
|
0x01 => if raw_packet.data_length == 4 {
|
|
Ok(NodeManagementCommand::RegisterNode {
|
|
device_id: Identifier::from(raw_packet.data)
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected 4 bytes")
|
|
},
|
|
// remove node
|
|
0x02 => Ok(NodeManagementCommand::RemoveNode),
|
|
0x0A => if raw_packet.data_length >= 4 && (raw_packet.data_length % 4 == 0) {
|
|
Ok(NodeManagementCommand::AcknowledgePackets {
|
|
packet_ids: raw_packet.data.chunks(4)
|
|
.map(|c| Identifier::from(c))
|
|
.collect()
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected at least 4 bytes and data_length%4=0")
|
|
}
|
|
// error
|
|
0x0E => if raw_packet.data_length >= 1 {
|
|
Ok(NodeManagementCommand::Error {
|
|
error_code: raw_packet.data[0],
|
|
metadata: raw_packet.data[1..].to_vec(),
|
|
})
|
|
} else {
|
|
build_invalid_input_err("expected at least 3 bytes")
|
|
},
|
|
_ => Err(io::Error::new(io::ErrorKind::InvalidInput, "command group is unsupported"))
|
|
}
|
|
}
|
|
}
|