diff --git a/src/message_handler.rs b/src/message_handler.rs index 0728d7a..9a5378e 100644 --- a/src/message_handler.rs +++ b/src/message_handler.rs @@ -43,53 +43,9 @@ impl MessageHandler { .unwrap_or("Unknown") } - pub fn msh_serial_msg(&mut self, payload: &[u8]) -> PyResult> { - let service_envelope = - ServiceEnvelope::decode(payload).map_err(|e| std::io::Error::from(e))?; - let packet = service_envelope - .packet - .ok_or(PyValueError::new_err("Missing packet in ServiceEnvelope"))?; - let mac_addr = format!("{:8x}", packet.from); - const SERIAL_APP: i32 = PortNum::SerialApp as i32; - let now = Local::now().fixed_offset(); - let host_info = HostInfo { - name: self.resolve(&mac_addr).to_owned(), - mac_address: mac_addr.clone(), - }; - let punches = match packet.payload_variant { - Some(PayloadVariant::Decoded(Data { - portnum: SERIAL_APP, - payload, - .. - })) => Ok(SiPunch::punches_from_payload(&payload[..], &host_info, now)), - _ => Err(std::io::Error::new( - std::io::ErrorKind::InvalidData, - format!("{}: Encrypted message or wrong portnum", host_info.name), - )), - }?; - - let mut result = Vec::with_capacity(punches.len()); - let status = self - .meshtastic_statuses - .entry(mac_addr) - .or_insert(MeshtasticRocStatus::new(host_info.name.clone())); - for punch in punches.into_iter() { - match punch { - Ok(punch) => { - let mut punch = punch.clone(); - status.punch(&punch); - if let Some(mac_addr) = self.meshtastic_override_mac.as_ref() { - punch.host_info.mac_address = mac_addr.clone(); - } - result.push(punch); - } - Err(err) => { - error!("{}", err); - } - } - } - - Ok(result) + #[pyo3(name = "meshtastic_serial_msg")] + pub fn msh_serial_msg_py(&mut self, payload: &[u8]) -> PyResult> { + Ok(self.msh_serial_msg(payload)?) } pub fn msh_status_update( @@ -202,6 +158,56 @@ impl MessageHandler { Ok(result) } + fn msh_serial_msg(&mut self, payload: &[u8]) -> std::io::Result> { + let service_envelope = + ServiceEnvelope::decode(payload).map_err(|e| std::io::Error::from(e))?; + let packet = service_envelope.packet.ok_or(std::io::Error::new( + std::io::ErrorKind::InvalidInput, + "Missing packet in ServiceEnvelope", + ))?; + let mac_addr = format!("{:8x}", packet.from); + const SERIAL_APP: i32 = PortNum::SerialApp as i32; + let now = Local::now().fixed_offset(); + let host_info = HostInfo { + name: self.resolve(&mac_addr).to_owned(), + mac_address: mac_addr.clone(), + }; + let punches = match packet.payload_variant { + Some(PayloadVariant::Decoded(Data { + portnum: SERIAL_APP, + payload, + .. + })) => Ok(SiPunch::punches_from_payload(&payload[..], &host_info, now)), + _ => Err(std::io::Error::new( + std::io::ErrorKind::InvalidData, + format!("{}: Encrypted message or wrong portnum", host_info.name), + )), + }?; + + let mut result = Vec::with_capacity(punches.len()); + let status = self + .meshtastic_statuses + .entry(mac_addr) + .or_insert(MeshtasticRocStatus::new(host_info.name.clone())); + for punch in punches.into_iter() { + match punch { + Ok(punch) => { + let mut punch = punch.clone(); + status.punch(&punch); + if let Some(mac_addr) = self.meshtastic_override_mac.as_ref() { + punch.host_info.mac_address = mac_addr.clone(); + } + result.push(punch); + } + Err(err) => { + error!("{}", err); + } + } + } + + Ok(result) + } + fn construct_punch( payload: &[u8], host_info: &HostInfo, @@ -241,6 +247,8 @@ mod test_punch { use std::collections::HashMap; use chrono::DateTime; + use meshtastic::protobufs::{Data, MeshPacket, PortNum, ServiceEnvelope}; + use meshtastic::Message as MeshtasticMessage; use prost::Message; use crate::{ @@ -283,4 +291,34 @@ mod test_punch { assert_eq!(punches[0].code, 47); assert_eq!(punches[0].card, 1715004); } + + #[test] + fn test_meshtastic_serial() { + let time = DateTime::parse_from_rfc3339("2023-11-23T10:00:03.793+00:00").unwrap(); + let punch = SiPunch::punch_to_bytes(47, time, 1715004, 2); + + const SERIAL_APP: i32 = PortNum::SerialApp as i32; + let envelope = ServiceEnvelope { + packet: Some(MeshPacket { + to: 0xabcd, + from: 0x1234, + payload_variant: Some(meshtastic::protobufs::mesh_packet::PayloadVariant::Decoded( + Data { + portnum: SERIAL_APP, + payload: punch.to_vec(), + ..Default::default() + }, + )), + ..Default::default() + }), + ..Default::default() + }; + + let message = envelope.encode_to_vec(); + let mut handler = MessageHandler::new(HashMap::new(), None); + let punches = handler.msh_serial_msg(&message[..]).unwrap(); + assert_eq!(punches.len(), 1); + assert_eq!(punches[0].code, 47); + assert_eq!(punches[0].card, 1715004); + } }