milstd1553b_parser/
encoding.rs

1//! Manchester encoding and decoding for MIL-STD-1553B
2
3use crate::error::{ParseError, Result};
4
5/// Manchester encoding type for MIL-STD-1553B
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum ManchesterType {
8    /// IEEE 802.3 Manchester: 0 = low-to-high, 1 = high-to-low
9    Ieee,
10    /// Thomas Manchester: 0 = high-to-low, 1 = low-to-high
11    Thomas,
12}
13
14impl ManchesterType {
15    /// Get the default Manchester encoding for MIL-STD-1553B
16    pub fn milstd() -> Self {
17        ManchesterType::Thomas
18    }
19}
20
21/// Manchester encoder for MIL-STD-1553B
22pub struct ManchesterEncoder;
23
24impl ManchesterEncoder {
25    /// Encode a single bit using Thomas Manchester encoding (MIL-STD-1553B standard)
26    ///
27    /// 0 = high-to-low transition (1, 0)
28    /// 1 = low-to-high transition (0, 1)
29    pub fn encode_bit(bit: bool) -> u8 {
30        match bit {
31            false => 0b10, // high-to-low
32            true => 0b01,  // low-to-high
33        }
34    }
35
36    /// Encode multiple bits (little-endian bit order)
37    ///
38    /// Returns a vector of bytes representing the Manchester-encoded data
39    pub fn encode_bits(data: &[bool]) -> Vec<u8> {
40        let mut result = Vec::with_capacity((data.len() + 3) / 4);
41        let mut byte = 0u8;
42        let mut bit_pos = 0;
43
44        for &bit in data {
45            let encoded = Self::encode_bit(bit);
46            byte |= (encoded & 0x3) << bit_pos;
47            bit_pos += 2;
48
49            if bit_pos == 8 {
50                result.push(byte);
51                byte = 0;
52                bit_pos = 0;
53            }
54        }
55
56        if bit_pos > 0 {
57            result.push(byte);
58        }
59
60        result
61    }
62
63    /// Encode a word (20 bits) into Manchester-encoded data
64    pub fn encode_word(word: u32) -> Vec<u8> {
65        let mut bits = Vec::with_capacity(20);
66        for i in 0..20 {
67            bits.push(((word >> i) & 1) != 0);
68        }
69        Self::encode_bits(&bits)
70    }
71}
72
73/// Manchester decoder for MIL-STD-1553B
74pub struct ManchesterDecoder;
75
76impl ManchesterDecoder {
77    /// Decode a single Manchester-encoded bit pair (Thomas encoding)
78    ///
79    /// Returns Ok(bit) on valid encoding, Err on invalid pattern
80    pub fn decode_bit(pair: u8) -> Result<bool> {
81        match pair & 0x3 {
82            0b01 => Ok(true),   // low-to-high = 1
83            0b10 => Ok(false),  // high-to-low = 0
84            _ => Err(ParseError::invalid_manchester(
85                format!("Invalid Manchester pattern: {:#04b}", pair),
86            )),
87        }
88    }
89
90    /// Decode a sequence of Manchester-encoded bits
91    ///
92    /// Each byte contains 4 Manchester-encoded bits (2 bits per bit)
93    pub fn decode_bits(data: &[u8], num_bits: usize) -> Result<Vec<bool>> {
94        let mut result = Vec::with_capacity(num_bits);
95
96        for &byte in data {
97            for shift in (0..8).step_by(2) {
98                if result.len() >= num_bits {
99                    break;
100                }
101                let pair = (byte >> shift) & 0x3;
102                result.push(Self::decode_bit(pair)?);
103            }
104
105            if result.len() >= num_bits {
106                break;
107            }
108        }
109
110        if result.len() < num_bits {
111            return Err(ParseError::insufficient_data(
112                format!("Expected {} bits, got {}", num_bits, result.len()),
113            ));
114        }
115
116        Ok(result)
117    }
118
119    /// Decode a Manchester-encoded word (20 bits)
120    ///
121    /// Expects 5 bytes (40 bits) of Manchester-encoded data
122    pub fn decode_word(data: &[u8]) -> Result<u32> {
123        if data.len() < 5 {
124            return Err(ParseError::insufficient_data(
125                format!("Expected 5 bytes for word, got {}", data.len()),
126            ));
127        }
128
129        let bits = Self::decode_bits(data, 20)?;
130        let mut word = 0u32;
131
132        for (i, &bit) in bits.iter().enumerate() {
133            if bit {
134                word |= 1 << i;
135            }
136        }
137
138        Ok(word)
139    }
140}
141
142#[cfg(test)]
143mod tests {
144    use super::*;
145
146    #[test]
147    fn test_manchester_encode_bit() {
148        assert_eq!(ManchesterEncoder::encode_bit(false), 0b10);
149        assert_eq!(ManchesterEncoder::encode_bit(true), 0b01);
150    }
151
152    #[test]
153    fn test_manchester_decode_bit() {
154        assert_eq!(ManchesterDecoder::decode_bit(0b10).unwrap(), false);
155        assert_eq!(ManchesterDecoder::decode_bit(0b01).unwrap(), true);
156        assert!(ManchesterDecoder::decode_bit(0b00).is_err());
157        assert!(ManchesterDecoder::decode_bit(0b11).is_err());
158    }
159
160    #[test]
161    fn test_manchester_encode_decode_roundtrip() {
162        let original_bits = vec![true, false, true, false, true, true, false, false];
163        let encoded = ManchesterEncoder::encode_bits(&original_bits);
164        let decoded = ManchesterDecoder::decode_bits(&encoded, original_bits.len()).unwrap();
165
166        assert_eq!(decoded, original_bits);
167    }
168
169    #[test]
170    fn test_manchester_word_encode_decode() {
171        let original_word = 0x12345u32;
172        let encoded = ManchesterEncoder::encode_word(original_word);
173        let decoded = ManchesterDecoder::decode_word(&encoded).unwrap();
174
175        assert_eq!(decoded, original_word);
176    }
177
178    #[test]
179    fn test_manchester_invalid_pattern() {
180        let invalid_data = vec![0b00, 0b11];
181        let result = ManchesterDecoder::decode_bits(&invalid_data, 2);
182        assert!(result.is_err());
183    }
184}