aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWill Dillon <william@housedillon.com>2025-11-06 08:41:29 +0000
committerWill Dillon <william@housedillon.com>2025-11-06 08:41:29 +0000
commit92883a366651ef3973f4de9fde2e3f9654502d32 (patch)
tree3379aee9fd8e1f6bf9c5dae6714de95b5c5afe5d /src
parent2/3 of packets pass tests (diff)
downloadmeshcore-rs-92883a366651ef3973f4de9fde2e3f9654502d32.tar.gz
meshcore-rs-92883a366651ef3973f4de9fde2e3f9654502d32.zip
All the packet types pass tests
Diffstat (limited to 'src')
-rw-r--r--src/crypto.rs1
-rw-r--r--src/packet.rs158
2 files changed, 141 insertions, 18 deletions
diff --git a/src/crypto.rs b/src/crypto.rs
index e3b2917..71c1cb3 100644
--- a/src/crypto.rs
+++ b/src/crypto.rs
@@ -7,6 +7,7 @@ use x25519_dalek::StaticSecret;
use hex::decode;
+#[derive(Debug)]
pub enum MeshcoreCryptoError {
KeyLengthError,
TryFromSliceError
diff --git a/src/packet.rs b/src/packet.rs
index 269835a..ad79688 100644
--- a/src/packet.rs
+++ b/src/packet.rs
@@ -63,7 +63,8 @@ impl From<u8> for PayloadVersion {
}
}
-#[derive(PartialEq, Debug, Clone)]
+#[derive(PartialEq, Debug, Clone, Difference)]
+#[difference(expose)]
enum PacketContent {
Request(Request),
Response(Response),
@@ -201,11 +202,7 @@ struct Text {
impl From<Bytes> for Text {
fn from(value: Bytes) -> Self {
- let mut text = Text {
- cipher: PeerToPeerCipher::from(value)
- };
-
- text
+ Text { cipher: PeerToPeerCipher::from(value) }
}
}
@@ -345,20 +342,52 @@ impl From<Bytes> for GroupText {
}
#[derive(PartialEq, Debug, Clone)]
-struct GroupData {}
+struct GroupData {
+ payload: Bytes
+}
impl From<Bytes> for GroupData {
fn from(value: Bytes) -> Self {
- todo!()
+ GroupData { payload: value }
}
}
-#[derive(PartialEq, Debug, Clone)]
-struct AnonReq {}
+#[derive(PartialEq, Debug, Clone, Difference)]
+#[difference(expose)]
+struct AnonReq {
+ destination: u8,
+ public_key: PublicKey,
+ mac: u16,
+ ciphertext: Bytes,
+ incomplete: bool
+}
impl From<Bytes> for AnonReq {
fn from(value: Bytes) -> Self {
- todo!()
+ let mut bytes = value;
+
+ let mut anon_req = AnonReq {
+ destination: 0x00,
+ public_key: PublicKey::default(),
+ mac: 0x0000,
+ ciphertext: Bytes::new(),
+ incomplete: false,
+ };
+
+ if bytes.len() == 0 { return anon_req; }
+ anon_req.destination = bytes.get_u8();
+
+ if bytes.len() < 32 { return anon_req; }
+ if let Ok(pub_key) = PublicKey::try_from(bytes.split_to(32)) {
+ anon_req.public_key = pub_key;
+ }
+
+ if bytes.len() < 2 { return anon_req; }
+ anon_req.mac = bytes.get_u16();
+
+ anon_req.ciphertext = bytes;
+ anon_req.incomplete = false;
+ anon_req
}
}
@@ -369,7 +398,9 @@ struct Path {
impl From<Bytes> for Path {
fn from(value: Bytes) -> Self {
- todo!()
+ Path {
+ cipher: PeerToPeerCipher::from(value)
+ }
}
}
@@ -409,11 +440,13 @@ impl From<Bytes> for Trace {
}
#[derive(PartialEq, Debug, Clone)]
-struct MultiPart {}
+struct MultiPart {
+ payload: Bytes
+}
impl From<Bytes> for MultiPart {
fn from(value: Bytes) -> Self {
- todo!()
+ MultiPart { payload: value }
}
}
@@ -454,8 +487,8 @@ impl From<Bytes> for Packet {
// The packet isn't long enough to contain the transport
if bytes.len() < 4 { return packet; }
- let t1 = bytes.get_u16();
- let t2 = bytes.get_u16();
+ let t1 = bytes.get_u16_le();
+ let t2 = bytes.get_u16_le();
[t1, t2]
},
_ => {
@@ -638,7 +671,7 @@ mod tests {
content: PacketContent::Raw(Raw { bytes: Bytes::copy_from_slice(&[0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19])}),
incomplete: false,
};
- let rhs_packet = Packet::from_str("3F0102030405060708090A10111213141516171819").unwrap();
+ let rhs_packet = Packet::from_str("3F0201040305060708090A10111213141516171819").unwrap();
assert!(lhs_packet == rhs_packet, "{}", print_compare(lhs_packet, rhs_packet));
}
@@ -841,7 +874,96 @@ mod tests {
cleartext: None, // "Just need some more high repeaters".to_owned()
incomplete: false
}),
- incomplete: false
+ incomplete: false
+ };
+
+ let rhs_packet = Packet::from_str(sample).unwrap();
+ assert!(lhs_packet == rhs_packet, "{}", print_compare(lhs_packet, rhs_packet));
+ }
+
+ #[test]
+ fn multipart() {
+ let sample = "2A0013E8C59624";
+
+ let lhs_packet = Packet {
+ route_type: RouteType::Direct,
+ version: PayloadVersion::VersionOne,
+ path: vec![],
+ transport: [0, 0],
+ raw_content: Bytes::copy_from_slice(&decode("13E8C59624").unwrap()),
+ content: PacketContent::Multipart(MultiPart {
+ payload: Bytes::copy_from_slice(&decode("13E8C59624").unwrap())
+ }),
+ incomplete: false
+ };
+
+ let rhs_packet = Packet::from_str(sample).unwrap();
+ assert!(lhs_packet == rhs_packet, "{}", print_compare(lhs_packet, rhs_packet));
+ }
+
+ #[test]
+ fn group_data() {
+ let sample = "18079DBB163F3C88707DF4C430C8A06A587CF7E827641C6521A5DE85581C8800793AF4A5497196CB5F24B92A33A9C8AA3BAE4F8C94E8E464849BCBF6333509C3941C47B7ABF85ECFD2FF06DA1A39575D155941F152F63300D2C31B5FAFBDA79637";
+
+ let lhs_packet = Packet {
+ route_type: RouteType::TransportFlood,
+ version: PayloadVersion::VersionOne,
+ path: vec![0x3C, 0x88, 0x70, 0x7D, 0xF4, 0xC4, 0x30, 0xC8, 0xA0, 0x6A, 0x58, 0x7C, 0xF7, 0xE8, 0x27, 0x64, 0x1C, 0x65, 0x21, 0xA5, 0xDE, 0x85, 0x58, 0x1C, 0x88, 0x00, 0x79, 0x3A, 0xF4, 0xA5, 0x49, 0x71, 0x96, 0xCB, 0x5F, 0x24, 0xB9, 0x2A, 0x33, 0xA9, 0xC8, 0xAA, 0x3B, 0xAE, 0x4F, 0x8C, 0x94, 0xE8, 0xE4, 0x64, 0x84, 0x9B, 0xCB, 0xF6, 0x33, 0x35, 0x09, 0xC3, 0x94, 0x1C, 0x47, 0xB7, 0xAB],
+ transport: [0x9d07, 0x16bb],
+ raw_content: Bytes::copy_from_slice(&decode("F85ECFD2FF06DA1A39575D155941F152F63300D2C31B5FAFBDA79637").unwrap()),
+ content: PacketContent::GroupData(GroupData {
+ payload: Bytes::copy_from_slice(&decode("F85ECFD2FF06DA1A39575D155941F152F63300D2C31B5FAFBDA79637").unwrap())
+ }),
+ incomplete: false
+ };
+
+ let rhs_packet = Packet::from_str(sample).unwrap();
+ assert!(lhs_packet == rhs_packet, "{}", print_compare(lhs_packet, rhs_packet));
+ }
+
+ #[test]
+ fn anon_req() {
+ let sample = "1d001234569df1f9661916901669666fb8025eccb9ddb0499cddad4c164fec219c8b8fd2db15a7138098557cc291928b4358fa7522ddd41d35c99fb78f0def2b3e673d73d2";
+
+ let lhs_packet = Packet {
+ route_type: RouteType::Flood,
+ version: PayloadVersion::VersionOne,
+ path: vec![],
+ transport: [0, 0],
+ raw_content: Bytes::copy_from_slice(&decode("1234569df1f9661916901669666fb8025eccb9ddb0499cddad4c164fec219c8b8fd2db15a7138098557cc291928b4358fa7522ddd41d35c99fb78f0def2b3e673d73d2").unwrap()),
+ content: PacketContent::AnonReq(AnonReq {
+ destination: 0x12,
+ public_key: PublicKey::try_from(Bytes::copy_from_slice(&decode("34569df1f9661916901669666fb8025eccb9ddb0499cddad4c164fec219c8b8f").unwrap())).unwrap(),
+ mac: 0xd2db,
+ ciphertext: Bytes::copy_from_slice(&decode("15a7138098557cc291928b4358fa7522ddd41d35c99fb78f0def2b3e673d73d2").unwrap()),
+ incomplete: false
+ }),
+ incomplete: false
+ };
+
+ let rhs_packet = Packet::from_str(sample).unwrap();
+ assert!(lhs_packet == rhs_packet, "{}", print_compare(lhs_packet, rhs_packet));
+ }
+
+ #[test]
+ fn path() {
+ let sample = "2107BA03127F7EA9221351768DD2DF32E1D02F5851379F5AFCC667AB273442FAB2943673F26DDBEB9595027474";
+
+ let lhs_packet = Packet {
+ route_type: RouteType::Flood,
+ version: PayloadVersion::VersionOne,
+ path: vec![0xBA, 0x03, 0x12, 0x7F, 0x7E, 0xA9, 0x22],
+ transport: [0, 0],
+ raw_content: Bytes::copy_from_slice(&decode("1351768DD2DF32E1D02F5851379F5AFCC667AB273442FAB2943673F26DDBEB9595027474").unwrap()),
+ content: PacketContent::Path(Path {
+ cipher: PeerToPeerCipher {
+ destination: 0x13,
+ source: 0x51,
+ mac: 0x768D,
+ ciphertext: Bytes::copy_from_slice(&decode("D2DF32E1D02F5851379F5AFCC667AB273442FAB2943673F26DDBEB9595027474").unwrap())
+ }
+ }),
+ incomplete: false
};
let rhs_packet = Packet::from_str(sample).unwrap();