feat: rewrite spec and proto

This commit is contained in:
Strix 2023-11-30 21:52:49 +01:00
parent 11e58c3d1d
commit 7999ac6103
No known key found for this signature in database
GPG key ID: 5F35B3B8537287A7
6 changed files with 298 additions and 144 deletions

View file

@ -12,13 +12,8 @@ pub enum NodeManagementCommand {
Ping,
RegisterNode { device_id: Identifier },
RemoveNode,
RegisterProperty {
property_name: String,
data_type: u8,
read_only: bool,
},
RemoveProperty {
property_name: String,
AcknowledgePackets {
packet_ids: Vec<Identifier>
},
Error {
error_code: u8,
@ -32,9 +27,8 @@ impl NodeManagementCommand {
NodeManagementCommand::Ping => 0x00,
NodeManagementCommand::RegisterNode { .. } => 0x01,
NodeManagementCommand::RemoveNode => 0x02,
NodeManagementCommand::RegisterProperty { .. } => 0x03,
NodeManagementCommand::RemoveProperty { .. } => 0x04,
NodeManagementCommand::Error { .. } => 0x0E
NodeManagementCommand::AcknowledgePackets { .. } => 0x0A,
NodeManagementCommand::Error { .. } => 0x0E,
}
}
}
@ -67,27 +61,16 @@ impl TryFrom<RawPacket> for NodeManagementCommand {
build_invalid_input_err("expected 4 bytes")
},
// remove node
0x02 => Ok(NodeManagementCommand::RemoveNode),
// register property
0x03 => if raw_packet.data_length == 34 {
Ok(NodeManagementCommand::RegisterProperty {
property_name: String::from_utf8(raw_packet.data[..32].to_vec())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"))?,
data_type: raw_packet.data[33],
read_only: raw_packet.data[34] != 0,
})
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 34 bytes")
},
// remove property
0x04 => if raw_packet.data_length == 32 {
Ok(NodeManagementCommand::RemoveProperty {
property_name: String::from_utf8(raw_packet.data.to_vec())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"))?
})
} else {
build_invalid_input_err("expected 32 bytes")
},
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 {

View file

@ -6,18 +6,21 @@ impl Into<Vec<u8>> for NodeManagementCommand {
match self {
NodeManagementCommand::Ping => vec![],
NodeManagementCommand::RegisterNode { device_id } => {
vec![device_id.bytes[0], device_id.bytes[1], device_id.bytes[2], device_id.bytes[3]]
},
vec![
device_id.bytes[0],
device_id.bytes[1],
device_id.bytes[2],
device_id.bytes[3],
]
}
NodeManagementCommand::RemoveNode => vec![],
NodeManagementCommand::RegisterProperty { property_name, data_type, read_only } => {
let mut vec = vec![];
vec.extend(property_name.into_bytes());
vec.push(data_type);
vec.push(read_only as u8);
vec
},
NodeManagementCommand::RemoveProperty { property_name } => property_name.into_bytes(),
NodeManagementCommand::Error { error_code, metadata } => {
NodeManagementCommand::AcknowledgePackets { packet_ids } =>
packet_ids.iter().map(|i| i.bytes).flatten().collect(),
NodeManagementCommand::Error {
error_code,
metadata,
} => {
let mut vec = vec![];
vec.push(error_code);
vec.extend(metadata);

View file

@ -1,15 +1,24 @@
use std::io;
use crate::data_types::DataType;
use crate::identifier::Identifier;
use crate::packet::packet_data::PacketData;
use crate::packet::raw_packet::RawPacket;
use crate::packet::{Packet, ToPacket};
use crate::packet::packet_data::PacketData;
use crate::prelude::as_u32_be;
use std::io;
pub mod vec;
#[derive(Debug, Clone)]
pub enum PropertyControlCommand {
Register {
property_name: String,
data_type: u8,
read_only: bool,
// TODO: descriptive
},
Remove {
property_name: String,
},
Get {
property_name: String,
data: DataType,
@ -34,21 +43,32 @@ pub enum PropertyControlCommand {
impl PropertyControlCommand {
pub fn command(&self) -> u8 {
match self {
PropertyControlCommand::Get { .. } => 0x10,
PropertyControlCommand::Set { .. } => 0x11,
PropertyControlCommand::Reset { .. } => 0x12,
PropertyControlCommand::Register { .. } => 0x10,
PropertyControlCommand::Remove { .. } => 0x11,
PropertyControlCommand::Get { .. } => 0x12,
PropertyControlCommand::Set { .. } => 0x13,
PropertyControlCommand::Reset { .. } => 0x14,
PropertyControlCommand::Subscribe { .. } => 0x1A,
PropertyControlCommand::Unsubscribe { .. } => 0x1B
PropertyControlCommand::Unsubscribe { .. } => 0x1B,
}
}
}
impl ToPacket for PropertyControlCommand {
fn to_packet(self, src: Identifier, dest: Identifier, packet_id: Identifier, reply_to: Identifier) -> Packet {
fn to_packet(
self,
src: Identifier,
dest: Identifier,
packet_id: Identifier,
reply_to: Identifier,
) -> Packet {
Packet {
src, dest, packet_id, reply_to,
src,
dest,
packet_id,
reply_to,
command: self.command(),
data: PacketData::PropertyControl(self.clone())
data: PacketData::PropertyControl(self.clone()),
}
}
}
@ -56,26 +76,56 @@ impl ToPacket for PropertyControlCommand {
impl TryFrom<RawPacket> for PropertyControlCommand {
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))
};
let build_invalid_input_err = |r: &str| Err(io::Error::new(io::ErrorKind::InvalidInput, r));
match raw_packet.command {
// get property
0x10 => if raw_packet.data_length == 33 {
Ok(PropertyControlCommand::Get {
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"))?,
data: DataType::try_from(raw_packet.data[0x34..].to_vec())?,
})
} else {
build_invalid_input_err("expected 33 bytes")
},
// set property
// remove node
0x10 => {
if raw_packet.data_length == 34 {
Ok(PropertyControlCommand::Register {
property_name: String::from_utf8(raw_packet.data[..32].to_vec()).map_err(
|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"),
)?,
data_type: raw_packet.data[33],
read_only: raw_packet.data[34] != 0,
})
} else {
build_invalid_input_err("expected 34 bytes")
}
}
// remove property
0x11 => {
if raw_packet.data_length == 32 {
Ok(PropertyControlCommand::Remove {
property_name: String::from_utf8(raw_packet.data.to_vec()).map_err(
|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"),
)?,
})
} else {
build_invalid_input_err("expected 32 bytes")
}
}
// get property
0x12 => {
if raw_packet.data_length == 33 {
Ok(PropertyControlCommand::Get {
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
data: DataType::try_from(raw_packet.data[0x34..].to_vec())?,
})
} else {
build_invalid_input_err("expected 33 bytes")
}
}
// set property
0x13 => {
if raw_packet.data_length == 33 {
Ok(PropertyControlCommand::Set {
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"))?,
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
data: DataType::try_from(raw_packet.data[0x34..].to_vec())?,
})
} else {
@ -83,11 +133,13 @@ impl TryFrom<RawPacket> for PropertyControlCommand {
}
}
// reset property
0x12 => {
0x14 => {
if raw_packet.data_length == 33 {
Ok(PropertyControlCommand::Reset {
property_name: String::from_utf8(raw_packet.data[..0x34].to_vec())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"))?,
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
})
} else {
build_invalid_input_err("expected 33 bytes")
@ -97,9 +149,13 @@ impl TryFrom<RawPacket> for PropertyControlCommand {
0x1A => {
if raw_packet.data_length == 36 {
Ok(PropertyControlCommand::Subscribe {
device_id: Identifier::from(as_u32_be(raw_packet.data[0x14..0x18].as_ref())),
device_id: Identifier::from(as_u32_be(
raw_packet.data[0x14..0x18].as_ref(),
)),
property_name: String::from_utf8(raw_packet.data[0x18..0x4C].to_vec())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"))?,
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
})
} else {
build_invalid_input_err("expected 36 bytes")
@ -109,15 +165,22 @@ impl TryFrom<RawPacket> for PropertyControlCommand {
0x1B => {
if raw_packet.data_length == 36 {
Ok(PropertyControlCommand::Unsubscribe {
device_id: Identifier::from(as_u32_be(raw_packet.data[0x14..0x18].as_ref())),
device_id: Identifier::from(as_u32_be(
raw_packet.data[0x14..0x18].as_ref(),
)),
property_name: String::from_utf8(raw_packet.data[0x18..0x4C].to_vec())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8"))?,
.map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "String is not UTF-8")
})?,
})
} else {
build_invalid_input_err("expected 36 bytes")
}
}
_ => Err(io::Error::new(io::ErrorKind::InvalidInput, "command group is unsupported"))
_ => Err(io::Error::new(
io::ErrorKind::InvalidInput,
"command group is unsupported",
)),
}
}
}

View file

@ -4,6 +4,14 @@ use crate::commands::property_control::PropertyControlCommand;
impl Into<Vec<u8>> for PropertyControlCommand {
fn into(self) -> Vec<u8> {
match self {
PropertyControlCommand::Register { property_name, data_type, read_only } => {
let mut vec = vec![];
vec.extend(property_name.into_bytes());
vec.push(data_type);
vec.push(read_only as u8);
vec
},
PropertyControlCommand::Remove { property_name } => property_name.into_bytes(),
PropertyControlCommand::Get { property_name, data } => {
let mut v = vec![];
v.extend(property_name.into_bytes());