1use std::borrow::Cow;
6use std::fmt;
7
8use bitflags::bitflags;
9use ironrdp_core::{
10 cast_length, ensure_fixed_part_size, ensure_size, invalid_field_err, other_err, Decode, DecodeError, DecodeResult,
11 Encode, EncodeResult, ReadCursor, WriteCursor,
12};
13use ironrdp_pdu::{read_padding, write_padding};
14use ironrdp_svc::SvcEncode;
15
16const SNDC_FORMATS: u8 = 0x07;
17const SNDC_QUALITYMODE: u8 = 0x0C;
18const SNDC_CRYPTKEY: u8 = 0x08;
19const SNDC_TRAINING: u8 = 0x06;
20const SNDC_WAVE: u8 = 0x02;
21const SNDC_WAVECONFIRM: u8 = 0x05;
22const SNDC_WAVEENCRYPT: u8 = 0x09;
23const SNDC_CLOSE: u8 = 0x01;
24const SNDC_WAVE2: u8 = 0x0D;
25const SNDC_VOLUME: u8 = 0x03;
26const SNDC_PITCH: u8 = 0x04;
27
28#[repr(u16)]
31#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq)]
32pub enum Version {
33 V2 = 0x02,
34 V5 = 0x05,
35 V6 = 0x06,
36 V8 = 0x08,
37}
38
39impl TryFrom<u16> for Version {
40 type Error = DecodeError;
41
42 fn try_from(value: u16) -> Result<Self, Self::Error> {
43 match value {
44 0x02 => Ok(Self::V2),
45 0x05 => Ok(Self::V5),
46 0x06 => Ok(Self::V6),
47 0x08 => Ok(Self::V8),
48 _ => Err(invalid_field_err!("Version", "unknown audio output version")),
49 }
50 }
51}
52
53impl From<Version> for u16 {
54 fn from(version: Version) -> Self {
55 version as u16
56 }
57}
58
59#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
62pub struct WaveFormat(u16);
63
64macro_rules! wave_formats {
65 (
66 $(
67 ($konst:ident, $num:expr);
68 )+
69 ) => {
70 impl WaveFormat {
71 $(
72 pub const $konst: WaveFormat = WaveFormat($num);
73 )+
74
75 fn as_str(&self) -> Option<&'static str> {
76 match self.0 {
77 $(
78 $num => Some(stringify!($konst)),
79 )+
80 _ => None
81 }
82 }
83 }
84 }
85}
86
87wave_formats! {
88 (UNKNOWN, 0x0000);
89 (PCM, 0x0001);
90 (ADPCM, 0x0002);
91 (IEEE_FLOAT, 0x0003);
92 (VSELP, 0x0004);
93 (IBM_CVSD, 0x0005);
94 (ALAW, 0x0006);
95 (MULAW, 0x0007);
96 (OKI_ADPCM, 0x0010);
97 (DVI_ADPCM, 0x0011);
98 (MEDIASPACE_ADPCM, 0x0012);
99 (SIERRA_ADPCM, 0x0013);
100 (G723_ADPCM, 0x0014);
101 (DIGISTD, 0x0015);
102 (DIGIFIX, 0x0016);
103 (DIALOGIC_OKI_ADPCM, 0x0017);
104 (MEDIAVISION_ADPCM, 0x0018);
105 (CU_CODEC, 0x0019);
106 (YAMAHA_ADPCM, 0x0020);
107 (SONARC, 0x0021);
108 (DSPGROUP_TRUESPEECH, 0x0022);
109 (ECHOSC1, 0x0023);
110 (AUDIOFILE_AF36, 0x0024);
111 (APTX, 0x0025);
112 (AUDIOFILE_AF10, 0x0026);
113 (PROSODY_1612, 0x0027);
114 (LRC, 0x0028);
115 (DOLBY_AC2, 0x0030);
116 (GSM610, 0x0031);
117 (MSNAUDIO, 0x0032);
118 (ANTEX_ADPCME, 0x0033);
119 (CONTROL_RES_VQLPC, 0x0034);
120 (DIGIREAL, 0x0035);
121 (DIGIADPCM, 0x0036);
122 (CONTROL_RES_CR10, 0x0037);
123 (NMS_VBXADPCM, 0x0038);
124 (ROLAND_RDAC, 0x0039);
125 (ECHOSC3, 0x003A);
126 (ROCKWELL_ADPCM, 0x003B);
127 (ROCKWELL_DIGITALK, 0x003C);
128 (XEBEC, 0x003D);
129 (G721_ADPCM, 0x0040);
130 (G728_CELP, 0x0041);
131 (MSG723, 0x0042);
132 (MPEG, 0x0050);
133 (RT24, 0x0052);
134 (PAC, 0x0053);
135 (MPEGLAYER3, 0x0055);
136 (LUCENT_G723, 0x0059);
137 (CIRRUS, 0x0060);
138 (ESPCM, 0x0061);
139 (VOXWARE, 0x0062);
140 (CANOPUS_ATRAC, 0x0063);
141 (G726_ADPCM, 0x0064);
142 (G722_ADPCM, 0x0065);
143 (DSAT, 0x0066);
144 (DSAT_DISPLAY, 0x0067);
145 (VOXWARE_BYTE_ALIGNED, 0x0069);
146 (VOXWARE_AC8, 0x0070);
147 (VOXWARE_AC10, 0x0071);
148 (VOXWARE_AC16, 0x0072);
149 (VOXWARE_AC20, 0x0073);
150 (VOXWARE_RT24, 0x0074);
151 (VOXWARE_RT29, 0x0075);
152 (VOXWARE_RT29HW, 0x0076);
153 (VOXWARE_VR12, 0x0077);
154 (VOXWARE_VR18, 0x0078);
155 (VOXWARE_TQ40, 0x0079);
156 (SOFTSOUND, 0x0080);
157 (VOXWARE_TQ60, 0x0081);
158 (MSRT24, 0x0082);
159 (G729A, 0x0083);
160 (MVI_MV12, 0x0084);
161 (DF_G726, 0x0085);
162 (DF_GSM610, 0x0086);
163 (ISIAUDIO, 0x0088);
164 (ONLIVE, 0x0089);
165 (SBC24, 0x0091);
166 (DOLBY_AC3_SPDIF, 0x0092);
167 (ZYXEL_ADPCM, 0x0097);
168 (PHILIPS_LPCBB, 0x0098);
169 (PACKED, 0x0099);
170 (RHETOREX_ADPCM, 0x0100);
171 (IRAT, 0x0101);
172 (VIVO_G723, 0x0111);
173 (VIVO_SIREN, 0x0112);
174 (DIGITAL_G723, 0x0123);
175 (WMAUDIO2, 0x0161);
176 (WMAUDIO3, 0x0162);
177 (WMAUDIO_LOSSLESS, 0x0163);
178 (CREATIVE_ADPCM, 0x0200);
179 (CREATIVE_FASTSPEECH8, 0x0202);
180 (CREATIVE_FASTSPEECH10, 0x0203);
181 (QUARTERDECK, 0x0220);
182 (FM_TOWNS_SND, 0x0300);
183 (BTV_DIGITAL, 0x0400);
184 (VME_VMPCM, 0x0680);
185 (OLIGSM, 0x1000);
186 (OLIADPCM, 0x1001);
187 (OLICELP, 0x1002);
188 (OLISBC, 0x1003);
189 (OLIOPR, 0x1004);
190 (LH_CODEC, 0x1100);
191 (NORRIS, 0x1400);
192 (SOUNDSPACE_MUSICOMPRESS, 0x1500);
193 (DVM, 0x2000);
194 (OPUS, 0x704F);
195 (AAC_MS, 0xA106);
196 (EXTENSIBLE, 0xFFFE);
197}
198
199impl fmt::Debug for WaveFormat {
200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 fmt::Debug::fmt(&self.0, f)
202 }
203}
204
205impl fmt::Display for WaveFormat {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 write!(f, "{} {}", self.0, self.as_str().unwrap_or("<unknown wave format>"))
208 }
209}
210
211#[derive(Debug, Clone, PartialEq, Eq, Hash)]
212pub struct AudioFormat {
213 pub format: WaveFormat,
214 pub n_channels: u16,
215 pub n_samples_per_sec: u32,
216 pub n_avg_bytes_per_sec: u32,
217 pub n_block_align: u16,
218 pub bits_per_sample: u16,
219 pub data: Option<Vec<u8>>,
220}
221
222impl AudioFormat {
223 const NAME: &'static str = "SERVER_AUDIO_VERSION_AND_FORMATS";
224
225 const FIXED_PART_SIZE: usize =
226 2 + 2 + 4 + 4 + 2 + 2 + 2 ;
233}
234
235impl Encode for AudioFormat {
236 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
237 ensure_size!(in: dst, size: self.size());
238
239 dst.write_u16(self.format.0);
240 dst.write_u16(self.n_channels);
241 dst.write_u32(self.n_samples_per_sec);
242 dst.write_u32(self.n_avg_bytes_per_sec);
243 dst.write_u16(self.n_block_align);
244 dst.write_u16(self.bits_per_sample);
245 let len = self.data.as_ref().map_or(0, |d| d.len());
246 dst.write_u16(cast_length!("AudioFormat::cbSize", len)?);
247 if let Some(data) = &self.data {
248 dst.write_slice(data);
249 }
250
251 Ok(())
252 }
253
254 fn name(&self) -> &'static str {
255 Self::NAME
256 }
257
258 fn size(&self) -> usize {
259 Self::FIXED_PART_SIZE
260 .checked_add(self.data.as_ref().map_or(0, |d| d.len()))
261 .expect("never overflow")
262 }
263}
264
265impl<'de> Decode<'de> for AudioFormat {
266 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
267 ensure_fixed_part_size!(in: src);
268
269 let format = WaveFormat(src.read_u16());
270 let n_channels = src.read_u16();
271 let n_samples_per_sec = src.read_u32();
272 let n_avg_bytes_per_sec = src.read_u32();
273 let n_block_align = src.read_u16();
274 let bits_per_sample = src.read_u16();
275 let cb_size = cast_length!("cbSize", src.read_u16())?;
276
277 ensure_size!(in: src, size: cb_size);
278 let data = if cb_size > 0 {
279 Some(src.read_slice(cb_size).into())
280 } else {
281 None
282 };
283
284 Ok(Self {
285 format,
286 n_channels,
287 n_samples_per_sec,
288 n_avg_bytes_per_sec,
289 n_block_align,
290 bits_per_sample,
291 data,
292 })
293 }
294}
295
296#[derive(Debug, Clone, PartialEq, Eq)]
297pub struct ServerAudioFormatPdu {
298 pub version: Version,
299 pub formats: Vec<AudioFormat>,
300}
301
302impl ServerAudioFormatPdu {
303 const NAME: &'static str = "SERVER_AUDIO_VERSION_AND_FORMATS";
304
305 const FIXED_PART_SIZE: usize =
306 4 + 4 + 4 + 2 + 2 + 1 + 2 + 1 ;
314}
315
316impl Encode for ServerAudioFormatPdu {
317 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
318 ensure_size!(in: dst, size: self.size());
319
320 write_padding!(dst, 4); write_padding!(dst, 4); write_padding!(dst, 4); write_padding!(dst, 2); dst.write_u16(cast_length!("AudioFormatPdu::n_formats", self.formats.len())?);
325 write_padding!(dst, 1); dst.write_u16(self.version.into());
327 write_padding!(dst, 1);
328 for fmt in self.formats.iter() {
329 fmt.encode(dst)?;
330 }
331
332 Ok(())
333 }
334
335 fn name(&self) -> &'static str {
336 Self::NAME
337 }
338
339 fn size(&self) -> usize {
340 Self::FIXED_PART_SIZE
341 .checked_add(self.formats.iter().map(|fmt| fmt.size()).sum::<usize>())
342 .expect("never overflow")
343 }
344}
345
346impl<'de> Decode<'de> for ServerAudioFormatPdu {
347 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
348 ensure_fixed_part_size!(in: src);
349
350 read_padding!(src, 4); read_padding!(src, 4); read_padding!(src, 4); read_padding!(src, 2); let n_formats = src.read_u16();
355 read_padding!(src, 1); let version = Version::try_from(src.read_u16())?;
357 read_padding!(src, 1);
358 let formats = (0..n_formats)
359 .map(|_| AudioFormat::decode(src))
360 .collect::<DecodeResult<_>>()?;
361
362 Ok(Self { version, formats })
363 }
364}
365
366bitflags! {
367 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
369 pub struct AudioFormatFlags: u32 {
370 const ALIVE = 0x0000_0001;
373 const VOLUME = 0x0000_0002;
376 const PITCH = 0x0000_00004;
379 const _ = !0;
381 }
382}
383
384#[derive(Debug, Clone, PartialEq, Eq)]
385pub struct ClientAudioFormatPdu {
386 pub version: Version,
387 pub flags: AudioFormatFlags,
388 pub formats: Vec<AudioFormat>,
389 pub volume_left: u16,
390 pub volume_right: u16,
391 pub pitch: u32,
392 pub dgram_port: u16,
393}
394
395impl ClientAudioFormatPdu {
396 const NAME: &'static str = "CLIENT_AUDIO_VERSION_AND_FORMATS";
397
398 const FIXED_PART_SIZE: usize =
399 4 + 4 + 4 + 2 + 2 + 1 + 2 + 1 ;
407}
408
409impl Encode for ClientAudioFormatPdu {
410 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
411 ensure_size!(in: dst, size: self.size());
412
413 dst.write_u32(self.flags.bits());
414 let volume = (u32::from(self.volume_right) << 16) | u32::from(self.volume_left);
415 dst.write_u32(volume);
416 dst.write_u32(self.pitch);
417 dst.write_u16_be(self.dgram_port);
418 dst.write_u16(cast_length!("AudioFormatPdu::n_formats", self.formats.len())?);
419 dst.write_u8(0); dst.write_u16(self.version.into());
421 write_padding!(dst, 1);
422 for fmt in self.formats.iter() {
423 fmt.encode(dst)?;
424 }
425
426 Ok(())
427 }
428
429 fn name(&self) -> &'static str {
430 Self::NAME
431 }
432
433 fn size(&self) -> usize {
434 Self::FIXED_PART_SIZE
435 .checked_add(self.formats.iter().map(|fmt| fmt.size()).sum::<usize>())
436 .expect("never overflow")
437 }
438}
439
440impl<'de> Decode<'de> for ClientAudioFormatPdu {
441 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
442 ensure_fixed_part_size!(in: src);
443
444 let flags = AudioFormatFlags::from_bits_truncate(src.read_u32());
445 let volume = src.read_u32();
446 let volume_left = (volume & 0xFFFF) as u16;
447 let volume_right = (volume >> 16) as u16;
448 let pitch = src.read_u32();
449 let dgram_port = src.read_u16_be();
450 let n_formats = src.read_u16();
451 let _block_no = src.read_u8();
452 let version = Version::try_from(src.read_u16())?;
453 read_padding!(src, 1);
454 let formats = (0..n_formats)
455 .map(|_| AudioFormat::decode(src))
456 .collect::<DecodeResult<_>>()?;
457
458 Ok(Self {
459 version,
460 flags,
461 formats,
462 volume_left,
463 volume_right,
464 pitch,
465 dgram_port,
466 })
467 }
468}
469
470#[repr(u16)]
471#[derive(Debug, Copy, Clone, PartialEq, Eq)]
472pub enum QualityMode {
473 Dynamic = 0x00,
474 Medium = 0x01,
475 High = 0x02,
476}
477
478impl TryFrom<u16> for QualityMode {
479 type Error = DecodeError;
480
481 fn try_from(value: u16) -> Result<Self, Self::Error> {
482 match value {
483 0x00 => Ok(Self::Dynamic),
484 0x01 => Ok(Self::Medium),
485 0x02 => Ok(Self::High),
486 _ => Err(invalid_field_err!("QualityMode", "unknown audio quality mode")),
487 }
488 }
489}
490
491impl From<QualityMode> for u16 {
492 fn from(mode: QualityMode) -> Self {
493 mode as u16
494 }
495}
496
497#[derive(Debug, Clone, PartialEq, Eq)]
498pub struct QualityModePdu {
499 pub quality_mode: QualityMode,
500}
501
502impl QualityModePdu {
503 const NAME: &'static str = "AUDIO_QUALITY_MODE";
504
505 const FIXED_PART_SIZE: usize =
506 2 + 2 ;
508}
509
510impl Encode for QualityModePdu {
511 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
512 ensure_size!(in: dst, size: self.size());
513
514 dst.write_u16(self.quality_mode.into());
515 write_padding!(dst, 2); Ok(())
518 }
519
520 fn name(&self) -> &'static str {
521 Self::NAME
522 }
523
524 fn size(&self) -> usize {
525 Self::FIXED_PART_SIZE
526 }
527}
528
529impl<'de> Decode<'de> for QualityModePdu {
530 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
531 ensure_fixed_part_size!(in: src);
532
533 let quality_mode = QualityMode::try_from(src.read_u16())?;
534 read_padding!(src, 2); Ok(Self { quality_mode })
537 }
538}
539
540#[derive(Debug, Clone, PartialEq, Eq)]
541pub struct CryptKeyPdu {
542 pub seed: [u8; 32],
543}
544
545impl CryptKeyPdu {
546 const NAME: &'static str = "SNDCRYPT";
547
548 const FIXED_PART_SIZE: usize =
549 4 + 32 ;
551}
552
553impl Encode for CryptKeyPdu {
554 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
555 ensure_size!(in: dst, size: self.size());
556
557 write_padding!(dst, 4); dst.write_array(self.seed);
559
560 Ok(())
561 }
562
563 fn name(&self) -> &'static str {
564 Self::NAME
565 }
566
567 fn size(&self) -> usize {
568 Self::FIXED_PART_SIZE
569 }
570}
571
572impl<'de> Decode<'de> for CryptKeyPdu {
573 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
574 ensure_fixed_part_size!(in: src);
575
576 read_padding!(src, 4); let seed = src.read_array();
578
579 Ok(Self { seed })
580 }
581}
582
583#[derive(Debug, Clone, PartialEq, Eq)]
584pub struct TrainingPdu {
585 pub timestamp: u16,
586 pub data: Vec<u8>,
587}
588
589impl TrainingPdu {
590 const NAME: &'static str = "SNDTRAINING";
591
592 const FIXED_PART_SIZE: usize =
593 2 + 2 ;
595}
596
597impl Encode for TrainingPdu {
598 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
599 ensure_size!(in: dst, size: self.size());
600
601 dst.write_u16(self.timestamp);
602 let len = if self.data.is_empty() {
603 0
604 } else {
605 self.size() + ServerAudioOutputPdu::FIXED_PART_SIZE
606 };
607 dst.write_u16(cast_length!("TrainingPdu::wPackSize", len)?);
608 dst.write_slice(&self.data);
609
610 Ok(())
611 }
612
613 fn name(&self) -> &'static str {
614 Self::NAME
615 }
616
617 fn size(&self) -> usize {
618 Self::FIXED_PART_SIZE
619 .checked_add(self.data.len())
620 .expect("never overflow")
621 }
622}
623
624impl<'de> Decode<'de> for TrainingPdu {
625 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
626 ensure_fixed_part_size!(in: src);
627
628 let timestamp = src.read_u16();
629 let len = src.read_u16() as usize;
630 let data = if len != 0 {
631 if len < Self::FIXED_PART_SIZE + ServerAudioOutputPdu::FIXED_PART_SIZE {
632 return Err(invalid_field_err!("TrainingPdu::wPackSize", "too small"));
633 }
634 let len = len - Self::FIXED_PART_SIZE - ServerAudioOutputPdu::FIXED_PART_SIZE;
635 ensure_size!(in: src, size: len);
636 src.read_slice(len).into()
637 } else {
638 Vec::new()
639 };
640
641 Ok(Self { timestamp, data })
642 }
643}
644
645#[derive(Debug, Clone, PartialEq, Eq)]
646pub struct TrainingConfirmPdu {
647 pub timestamp: u16,
648 pub pack_size: u16,
649}
650
651impl TrainingConfirmPdu {
652 const NAME: &'static str = "SNDTRAININGCONFIRM";
653
654 const FIXED_PART_SIZE: usize =
655 2 + 2 ;
657}
658
659impl Encode for TrainingConfirmPdu {
660 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
661 ensure_size!(in: dst, size: self.size());
662
663 dst.write_u16(self.timestamp);
664 dst.write_u16(self.pack_size);
665
666 Ok(())
667 }
668
669 fn name(&self) -> &'static str {
670 Self::NAME
671 }
672
673 fn size(&self) -> usize {
674 Self::FIXED_PART_SIZE
675 }
676}
677
678impl<'de> Decode<'de> for TrainingConfirmPdu {
679 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
680 ensure_fixed_part_size!(in: src);
681
682 let timestamp = src.read_u16();
683 let pack_size = src.read_u16();
684
685 Ok(Self { timestamp, pack_size })
686 }
687}
688
689#[derive(Debug, Clone, PartialEq, Eq)]
690pub struct WaveInfoPdu {
691 pub timestamp: u16,
692 pub format_no: u16,
693 pub block_no: u8,
694 pub data: [u8; 4],
695}
696
697impl WaveInfoPdu {
698 const NAME: &'static str = "SNDWAVEINFO";
699
700 const FIXED_PART_SIZE: usize =
701 2 + 2 + 1 + 3 + 4 ;
706}
707
708impl Encode for WaveInfoPdu {
709 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
710 ensure_size!(in: dst, size: self.size());
711
712 dst.write_u16(self.timestamp);
713 dst.write_u16(self.format_no);
714 dst.write_u8(self.block_no);
715 write_padding!(dst, 3);
716 dst.write_array(self.data);
717
718 Ok(())
719 }
720
721 fn name(&self) -> &'static str {
722 Self::NAME
723 }
724
725 fn size(&self) -> usize {
726 Self::FIXED_PART_SIZE
727 }
728}
729
730impl<'de> Decode<'de> for WaveInfoPdu {
731 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
732 ensure_fixed_part_size!(in: src);
733
734 let timestamp = src.read_u16();
735 let format_no = src.read_u16();
736 let block_no = src.read_u8();
737 read_padding!(src, 3);
738 let data = src.read_array();
739
740 Ok(Self {
741 timestamp,
742 format_no,
743 block_no,
744 data,
745 })
746 }
747}
748
749#[derive(Debug, Clone, PartialEq, Eq)]
750pub struct SndWavePdu {
751 pub data: Vec<u8>,
752}
753
754impl SndWavePdu {
755 const NAME: &'static str = "SNDWAVE";
756
757 const FIXED_PART_SIZE: usize = 4 ;
758}
759
760impl Encode for SndWavePdu {
761 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
762 ensure_size!(in: dst, size: self.size());
763
764 write_padding!(dst, 4);
765 dst.write_slice(&self.data);
766
767 Ok(())
768 }
769
770 fn name(&self) -> &'static str {
771 Self::NAME
772 }
773
774 fn size(&self) -> usize {
775 Self::FIXED_PART_SIZE
776 .checked_add(self.data.len())
777 .expect("never overflow")
778 }
779}
780
781impl SndWavePdu {
782 fn decode(src: &mut ReadCursor<'_>, data_len: usize) -> DecodeResult<Self> {
783 ensure_fixed_part_size!(in: src);
784
785 read_padding!(src, 4);
786 ensure_size!(in: src, size: data_len);
787 let data = src.read_slice(data_len).into();
788
789 Ok(Self { data })
790 }
791}
792
793#[derive(Debug, Clone, PartialEq, Eq)]
795pub struct WavePdu<'a> {
796 pub timestamp: u16,
797 pub format_no: u16,
798 pub block_no: u8,
799 pub data: Cow<'a, [u8]>,
800}
801
802impl WavePdu<'_> {
803 const NAME: &'static str = "WavePdu";
804
805 fn body_size(&self) -> usize {
806 (WaveInfoPdu::FIXED_PART_SIZE - 4)
807 .checked_add(self.data.len())
808 .expect("never overflow")
809 }
810}
811
812impl Encode for WavePdu<'_> {
813 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
814 let info = WaveInfoPdu {
815 timestamp: self.timestamp,
816 format_no: self.format_no,
817 block_no: self.block_no,
818 data: self.data[0..4]
819 .try_into()
820 .map_err(|e| other_err!("invalid data", source: e))?,
821 };
822 let wave = SndWavePdu {
823 data: self.data[4..].into(),
824 };
825 info.encode(dst)?;
826 wave.encode(dst)?;
827 Ok(())
828 }
829
830 fn name(&self) -> &'static str {
831 Self::NAME
832 }
833
834 fn size(&self) -> usize {
835 (WaveInfoPdu::FIXED_PART_SIZE + SndWavePdu::FIXED_PART_SIZE - 4)
836 .checked_add(self.data.len())
837 .expect("never overflow")
838 }
839}
840
841impl WavePdu<'_> {
842 fn decode(src: &mut ReadCursor<'_>, body_size: u16) -> DecodeResult<Self> {
843 let info = WaveInfoPdu::decode(src)?;
844 let body_size = body_size as usize;
845 let data_len = body_size
846 .checked_sub(info.size())
847 .ok_or_else(|| invalid_field_err!("Length", "WaveInfo body_size is too small"))?;
848 let wave = SndWavePdu::decode(src, data_len)?;
849
850 let mut data = Vec::with_capacity(wave.size());
851 data.extend_from_slice(&info.data);
852 data.extend_from_slice(&wave.data);
853
854 Ok(Self {
855 timestamp: info.timestamp,
856 format_no: info.format_no,
857 block_no: info.block_no,
858 data: data.into(),
859 })
860 }
861}
862
863#[derive(Debug, Clone, PartialEq, Eq)]
864pub struct WaveConfirmPdu {
865 pub timestamp: u16,
866 pub block_no: u8,
867}
868
869impl WaveConfirmPdu {
870 const NAME: &'static str = "SNDWAV_CONFIRM";
871
872 const FIXED_PART_SIZE: usize =
873 2 + 1 + 1 ;
876}
877
878impl Encode for WaveConfirmPdu {
879 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
880 ensure_size!(in: dst, size: self.size());
881
882 dst.write_u16(self.timestamp);
883 dst.write_u8(self.block_no);
884 write_padding!(dst, 1);
885
886 Ok(())
887 }
888
889 fn name(&self) -> &'static str {
890 Self::NAME
891 }
892
893 fn size(&self) -> usize {
894 Self::FIXED_PART_SIZE
895 }
896}
897
898impl<'de> Decode<'de> for WaveConfirmPdu {
899 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
900 ensure_fixed_part_size!(in: src);
901
902 let timestamp = src.read_u16();
903 let block_no = src.read_u8();
904 read_padding!(src, 1);
905
906 Ok(Self { timestamp, block_no })
907 }
908}
909
910#[derive(Debug, Clone, PartialEq, Eq)]
911pub struct WaveEncryptPdu {
912 pub timestamp: u16,
913 pub format_no: u16,
914 pub block_no: u8,
915 pub signature: Option<[u8; 8]>,
916 pub data: Vec<u8>,
918}
919
920impl WaveEncryptPdu {
921 const NAME: &'static str = "SNDWAVECRYPT";
922
923 const FIXED_PART_SIZE: usize =
924 2 + 2 + 1 + 3 ;
928}
929
930impl Encode for WaveEncryptPdu {
931 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
932 ensure_size!(in: dst, size: self.size());
933
934 dst.write_u16(self.timestamp);
935 dst.write_u16(self.format_no);
936 dst.write_u8(self.block_no);
937 write_padding!(dst, 3);
938 if let Some(sig) = self.signature.as_ref() {
939 dst.write_slice(sig);
940 }
941 dst.write_slice(&self.data);
942
943 Ok(())
944 }
945
946 fn name(&self) -> &'static str {
947 Self::NAME
948 }
949
950 fn size(&self) -> usize {
951 Self::FIXED_PART_SIZE
952 .checked_add(self.signature.map_or(0, |_| 8))
953 .unwrap()
954 .checked_add(self.data.len())
955 .expect("never overflow")
956 }
957}
958
959impl WaveEncryptPdu {
960 fn decode(src: &mut ReadCursor<'_>, version: Version) -> DecodeResult<Self> {
961 ensure_fixed_part_size!(in: src);
962
963 let timestamp = src.read_u16();
964 let format_no = src.read_u16();
965 let block_no = src.read_u8();
966 read_padding!(src, 3);
967 let signature = if version >= Version::V5 {
968 ensure_size!(in: src, size: 8);
969 Some(src.read_array())
970 } else {
971 None
972 };
973 let data = src.read_remaining().into();
974
975 Ok(Self {
976 timestamp,
977 format_no,
978 block_no,
979 signature,
980 data,
981 })
982 }
983}
984
985#[derive(Clone, PartialEq, Eq)]
986pub struct Wave2Pdu<'a> {
987 pub timestamp: u16,
988 pub format_no: u16,
989 pub block_no: u8,
990 pub audio_timestamp: u32,
991 pub data: Cow<'a, [u8]>,
992}
993
994impl fmt::Debug for Wave2Pdu<'_> {
995 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
996 f.debug_struct("Wave2Pdu")
997 .field("timestamp", &self.timestamp)
998 .field("format_no", &self.format_no)
999 .field("block_no", &self.block_no)
1000 .field("audio_timestamp", &self.audio_timestamp)
1001 .finish()
1002 }
1003}
1004
1005impl Wave2Pdu<'_> {
1006 const NAME: &'static str = "SNDWAVE2";
1007
1008 const FIXED_PART_SIZE: usize =
1009 2 + 2 + 1 + 3 + 4 ;
1014}
1015
1016impl Encode for Wave2Pdu<'_> {
1017 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
1018 ensure_size!(in: dst, size: self.size());
1019
1020 dst.write_u16(self.timestamp);
1021 dst.write_u16(self.format_no);
1022 dst.write_u8(self.block_no);
1023 write_padding!(dst, 3);
1024 dst.write_u32(self.audio_timestamp);
1025 dst.write_slice(&self.data);
1026
1027 Ok(())
1028 }
1029
1030 fn name(&self) -> &'static str {
1031 Self::NAME
1032 }
1033
1034 fn size(&self) -> usize {
1035 Self::FIXED_PART_SIZE
1036 .checked_add(self.data.len())
1037 .expect("never overflow")
1038 }
1039}
1040
1041impl<'de> Decode<'de> for Wave2Pdu<'_> {
1042 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
1043 ensure_fixed_part_size!(in: src);
1044
1045 let timestamp = src.read_u16();
1046 let format_no = src.read_u16();
1047 let block_no = src.read_u8();
1048 read_padding!(src, 3);
1049 let audio_timestamp = src.read_u32();
1050 let data = src.read_remaining().to_vec().into();
1051
1052 Ok(Self {
1053 timestamp,
1054 format_no,
1055 block_no,
1056 audio_timestamp,
1057 data,
1058 })
1059 }
1060}
1061
1062#[derive(Debug, Clone, PartialEq, Eq)]
1063pub struct VolumePdu {
1064 pub volume_left: u16,
1065 pub volume_right: u16,
1066}
1067
1068impl VolumePdu {
1069 const NAME: &'static str = "SNDVOL";
1070
1071 const FIXED_PART_SIZE: usize = 4;
1072}
1073
1074impl Encode for VolumePdu {
1075 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
1076 ensure_size!(in: dst, size: self.size());
1077
1078 let volume = (u32::from(self.volume_right) << 16) | u32::from(self.volume_left);
1079 dst.write_u32(volume);
1080
1081 Ok(())
1082 }
1083
1084 fn name(&self) -> &'static str {
1085 Self::NAME
1086 }
1087
1088 fn size(&self) -> usize {
1089 Self::FIXED_PART_SIZE
1090 }
1091}
1092
1093impl<'de> Decode<'de> for VolumePdu {
1094 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
1095 ensure_fixed_part_size!(in: src);
1096
1097 let volume = src.read_u32();
1098 let volume_left = (volume & 0xFFFF) as u16;
1099 let volume_right = (volume >> 16) as u16;
1100
1101 Ok(Self {
1102 volume_left,
1103 volume_right,
1104 })
1105 }
1106}
1107
1108#[derive(Debug, Clone, PartialEq, Eq)]
1109pub struct PitchPdu {
1110 pub pitch: u32,
1111}
1112
1113impl PitchPdu {
1114 const NAME: &'static str = "SNDPITCH";
1115
1116 const FIXED_PART_SIZE: usize = 4;
1117}
1118
1119impl Encode for PitchPdu {
1120 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
1121 ensure_size!(in: dst, size: self.size());
1122
1123 dst.write_u32(self.pitch);
1124
1125 Ok(())
1126 }
1127
1128 fn name(&self) -> &'static str {
1129 Self::NAME
1130 }
1131
1132 fn size(&self) -> usize {
1133 Self::FIXED_PART_SIZE
1134 }
1135}
1136
1137impl<'de> Decode<'de> for PitchPdu {
1138 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
1139 ensure_fixed_part_size!(in: src);
1140
1141 let pitch = src.read_u32();
1142
1143 Ok(Self { pitch })
1144 }
1145}
1146
1147#[derive(Debug, Clone, PartialEq, Eq)]
1149pub enum ServerAudioOutputPdu<'a> {
1150 AudioFormat(ServerAudioFormatPdu),
1151 CryptKey(CryptKeyPdu),
1152 Training(TrainingPdu),
1153 Wave(WavePdu<'a>),
1154 WaveEncrypt(WaveEncryptPdu),
1155 Close,
1156 Wave2(Wave2Pdu<'a>),
1157 Volume(VolumePdu),
1158 Pitch(PitchPdu),
1159}
1160
1161impl ServerAudioOutputPdu<'_> {
1162 const NAME: &'static str = "ServerAudioOutputPdu";
1163
1164 const FIXED_PART_SIZE: usize = 1 + 1 + 2 ;
1165}
1166
1167impl Encode for ServerAudioOutputPdu<'_> {
1168 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
1169 ensure_fixed_part_size!(in: dst);
1170
1171 let (msg_type, pdu_size) = match self {
1172 Self::AudioFormat(pdu) => (SNDC_FORMATS, pdu.size()),
1173 Self::CryptKey(pdu) => (SNDC_CRYPTKEY, pdu.size()),
1174 Self::Training(pdu) => (SNDC_TRAINING, pdu.size()),
1175 Self::Wave(pdu) => (SNDC_WAVE, pdu.body_size()),
1176 Self::WaveEncrypt(pdu) => (SNDC_WAVEENCRYPT, pdu.size()),
1177 Self::Close => (SNDC_CLOSE, 0),
1178 Self::Wave2(pdu) => (SNDC_WAVE2, pdu.size()),
1179 Self::Volume(pdu) => (SNDC_VOLUME, pdu.size()),
1180 Self::Pitch(pdu) => (SNDC_PITCH, pdu.size()),
1181 };
1182
1183 dst.write_u8(msg_type);
1184 write_padding!(dst, 1);
1185 dst.write_u16(cast_length!("ServerAudioOutputPdu::bodySize", pdu_size)?);
1186
1187 match self {
1188 Self::AudioFormat(pdu) => pdu.encode(dst),
1189 Self::CryptKey(pdu) => pdu.encode(dst),
1190 Self::Training(pdu) => pdu.encode(dst),
1191 Self::Wave(pdu) => pdu.encode(dst),
1192 Self::WaveEncrypt(pdu) => pdu.encode(dst),
1193 Self::Close => Ok(()),
1194 Self::Wave2(pdu) => pdu.encode(dst),
1195 Self::Volume(pdu) => pdu.encode(dst),
1196 Self::Pitch(pdu) => pdu.encode(dst),
1197 }?;
1198
1199 Ok(())
1200 }
1201
1202 fn name(&self) -> &'static str {
1203 Self::NAME
1204 }
1205
1206 fn size(&self) -> usize {
1207 Self::FIXED_PART_SIZE
1208 .checked_add(match self {
1209 Self::AudioFormat(pdu) => pdu.size(),
1210 Self::CryptKey(pdu) => pdu.size(),
1211 Self::Training(pdu) => pdu.size(),
1212 Self::Wave(pdu) => pdu.size(),
1213 Self::WaveEncrypt(pdu) => pdu.size(),
1214 Self::Close => 0,
1215 Self::Wave2(pdu) => pdu.size(),
1216 Self::Volume(pdu) => pdu.size(),
1217 Self::Pitch(pdu) => pdu.size(),
1218 })
1219 .expect("never overflow")
1220 }
1221}
1222
1223impl<'de> Decode<'de> for ServerAudioOutputPdu<'_> {
1224 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
1225 ensure_fixed_part_size!(in: src);
1226
1227 let msg_type = src.read_u8();
1228 read_padding!(src, 1);
1229 let body_size = src.read_u16();
1230
1231 match msg_type {
1232 SNDC_FORMATS => {
1233 let pdu = ServerAudioFormatPdu::decode(src)?;
1234 Ok(Self::AudioFormat(pdu))
1235 }
1236 SNDC_CRYPTKEY => {
1237 let pdu = CryptKeyPdu::decode(src)?;
1238 Ok(Self::CryptKey(pdu))
1239 }
1240 SNDC_TRAINING => {
1241 let pdu = TrainingPdu::decode(src)?;
1242 Ok(Self::Training(pdu))
1243 }
1244 SNDC_WAVE => {
1245 let pdu = WavePdu::decode(src, body_size)?;
1246 Ok(Self::Wave(pdu))
1247 }
1248 SNDC_WAVEENCRYPT => {
1249 let pdu = WaveEncryptPdu::decode(src, Version::V5)?;
1250 Ok(Self::WaveEncrypt(pdu))
1251 }
1252 SNDC_CLOSE => Ok(Self::Close),
1253 SNDC_WAVE2 => {
1254 let pdu = Wave2Pdu::decode(src)?;
1255 Ok(Self::Wave2(pdu))
1256 }
1257 SNDC_VOLUME => {
1258 let pdu = VolumePdu::decode(src)?;
1259 Ok(Self::Volume(pdu))
1260 }
1261 SNDC_PITCH => {
1262 let pdu = PitchPdu::decode(src)?;
1263 Ok(Self::Pitch(pdu))
1264 }
1265 _ => Err(invalid_field_err!(
1266 "ServerAudioOutputPdu::msgType",
1267 "Unknown audio output PDU type"
1268 )),
1269 }
1270 }
1271}
1272
1273impl SvcEncode for ServerAudioOutputPdu<'_> {}
1274
1275#[derive(Debug, Clone, PartialEq, Eq)]
1277pub enum ClientAudioOutputPdu {
1278 AudioFormat(ClientAudioFormatPdu),
1279 QualityMode(QualityModePdu),
1280 TrainingConfirm(TrainingConfirmPdu),
1281 WaveConfirm(WaveConfirmPdu),
1282}
1283
1284impl ClientAudioOutputPdu {
1285 const NAME: &'static str = "ClientAudioOutputPdu";
1286
1287 const FIXED_PART_SIZE: usize = 1 + 1 + 2 ;
1288}
1289
1290impl Encode for ClientAudioOutputPdu {
1291 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
1292 ensure_fixed_part_size!(in: dst);
1293
1294 let (msg_type, body_size) = match self {
1295 Self::AudioFormat(pdu) => (SNDC_FORMATS, pdu.size()),
1296 Self::QualityMode(pdu) => (SNDC_QUALITYMODE, pdu.size()),
1297 Self::TrainingConfirm(pdu) => (SNDC_TRAINING, pdu.size()),
1298 Self::WaveConfirm(pdu) => (SNDC_WAVECONFIRM, pdu.size()),
1299 };
1300
1301 dst.write_u8(msg_type);
1302 write_padding!(dst, 1);
1303 dst.write_u16(cast_length!("ClientAudioOutputPdu::bodySize", body_size)?);
1304
1305 match self {
1306 Self::AudioFormat(pdu) => pdu.encode(dst),
1307 Self::QualityMode(pdu) => pdu.encode(dst),
1308 Self::TrainingConfirm(pdu) => pdu.encode(dst),
1309 Self::WaveConfirm(pdu) => pdu.encode(dst),
1310 }?;
1311
1312 Ok(())
1313 }
1314
1315 fn name(&self) -> &'static str {
1316 Self::NAME
1317 }
1318
1319 fn size(&self) -> usize {
1320 Self::FIXED_PART_SIZE
1321 .checked_add(match self {
1322 Self::AudioFormat(pdu) => pdu.size(),
1323 Self::QualityMode(pdu) => pdu.size(),
1324 Self::TrainingConfirm(pdu) => pdu.size(),
1325 Self::WaveConfirm(pdu) => pdu.size(),
1326 })
1327 .expect("never overflow")
1328 }
1329}
1330
1331impl<'de> Decode<'de> for ClientAudioOutputPdu {
1332 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
1333 ensure_fixed_part_size!(in: src);
1334
1335 let msg_type = src.read_u8();
1336 read_padding!(src, 1);
1337 let _body_size = src.read_u16();
1338
1339 match msg_type {
1340 SNDC_FORMATS => {
1341 let pdu = ClientAudioFormatPdu::decode(src)?;
1342 Ok(Self::AudioFormat(pdu))
1343 }
1344 SNDC_QUALITYMODE => {
1345 let pdu = QualityModePdu::decode(src)?;
1346 Ok(Self::QualityMode(pdu))
1347 }
1348 SNDC_TRAINING => {
1349 let pdu = TrainingConfirmPdu::decode(src)?;
1350 Ok(Self::TrainingConfirm(pdu))
1351 }
1352 SNDC_WAVECONFIRM => {
1353 let pdu = WaveConfirmPdu::decode(src)?;
1354 Ok(Self::WaveConfirm(pdu))
1355 }
1356 _ => Err(invalid_field_err!(
1357 "ClientAudioOutputPdu::msgType",
1358 "Unknown audio output PDU type"
1359 )),
1360 }
1361 }
1362}
1363
1364impl SvcEncode for ClientAudioOutputPdu {}