timex_datalink/protocol_4/
sound_theme.rs1use crate::PacketGenerator;
6use crate::helpers::cpacket_paginator::paginate_cpackets;
7
8pub struct SoundTheme {
10 pub sound_theme_data: Vec<u8>,
12}
13
14impl PacketGenerator for SoundTheme {
15 fn packets(&self) -> Vec<Vec<u8>> {
16 const CPACKET_SECT: [u8; 2] = [0x90, 0x03];
18 const CPACKET_DATA: [u8; 2] = [0x91, 0x03];
19 const CPACKET_END: [u8; 2] = [0x92, 0x03];
20 const CPACKET_DATA_LENGTH: usize = 32;
21
22 const SOUND_DATA_HEADER: &[u8] = &[0x25, 0x04, 0x19, 0x69];
24
25 let sound_data = if self.sound_theme_data.starts_with(SOUND_DATA_HEADER) {
26 &self.sound_theme_data[SOUND_DATA_HEADER.len()..]
27 } else {
28 &self.sound_theme_data
29 };
30
31 let offset = 0x100 - sound_data.len();
33
34 let payloads = paginate_cpackets(&CPACKET_DATA, CPACKET_DATA_LENGTH, sound_data);
36 let mut load_sect = Vec::new();
37 load_sect.extend_from_slice(&CPACKET_SECT);
38 load_sect.push(payloads.len() as u8);
39 load_sect.push(offset as u8);
40
41 let end_packet = CPACKET_END.to_vec();
43
44 let mut all_packets = Vec::with_capacity(payloads.len() + 2);
46 all_packets.push(load_sect);
47 all_packets.extend(payloads);
48 all_packets.push(end_packet);
49
50 use crate::helpers::crc_packets_wrapper::wrap_packets_with_crc;
52 wrap_packets_with_crc(all_packets)
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 const EXAMPLE_SPC: &[u8] = include_bytes!("../../fixtures/EXAMPLE.SPC");
63
64 #[test]
65 fn test_sound_theme() {
66 let sound_theme = SoundTheme {
67 sound_theme_data: EXAMPLE_SPC.to_vec(),
68 };
69
70 #[rustfmt::skip]
72 let expected = vec![
73 vec![7, 144, 3, 2, 215, 254, 41],
74 vec![38, 145, 3, 1, 98, 105, 110, 97, 114, 121, 32, 115, 111, 117, 110, 100, 32, 100, 97, 116, 97, 32, 116, 104, 97, 116, 32, 103, 101, 116, 115, 32, 115, 101, 110, 116, 28, 235],
75 vec![15, 145, 3, 2, 32, 118, 101, 114, 98, 97, 116, 105, 109, 75, 236],
76 vec![5, 146, 3, 96, 61]
77 ];
78
79 assert_eq!(sound_theme.packets(), expected);
80 }
81}