1use bt_bap::types::BroadcastId;
6use bt_common::core::ltv::LtValue;
7use bt_common::core::{AddressType, AdvertisingSetId, PeriodicAdvertisingInterval};
8use bt_common::generic_audio::metadata_ltv::*;
9use bt_common::packet_encoding::{Decodable, Encodable, Error as PacketError};
10use bt_common::{decodable_enum, Uuid};
11use std::str::FromStr;
12
13pub const ADDRESS_BYTE_SIZE: usize = 6;
14const NUM_SUBGROUPS_BYTE_SIZE: usize = 1;
15const PA_SYNC_BYTE_SIZE: usize = 1;
16const SOURCE_ID_BYTE_SIZE: usize = 1;
17
18pub const BROADCAST_AUDIO_SCAN_CONTROL_POINT_UUID: Uuid = Uuid::from_u16(0x2BC7);
21pub const BROADCAST_RECEIVE_STATE_UUID: Uuid = Uuid::from_u16(0x2BC8);
22
23pub type SourceId = u8;
24
25pub type SubgroupIndex = u8;
28
29pub type BisIndex = u8;
31
32decodable_enum! {
33 pub enum ControlPointOpcode<u8, bt_common::packet_encoding::Error, OutOfRange> {
34 RemoteScanStopped = 0x00,
35 RemoteScanStarted = 0x01,
36 AddSource = 0x02,
37 ModifySource = 0x03,
38 SetBroadcastCode = 0x04,
39 RemoveSource = 0x05,
40 }
41}
42
43impl ControlPointOpcode {
46 const BYTE_SIZE: usize = 1;
47}
48
49pub trait ControlPointOperation: Encodable<Error = PacketError> {
56 fn opcode() -> ControlPointOpcode;
58
59 fn check_opcode(raw_value: u8) -> Result<ControlPointOpcode, PacketError> {
62 let expected = Self::opcode();
63 let got = ControlPointOpcode::try_from(raw_value)?;
64 if got != expected {
65 return Err(PacketError::InvalidParameter(format!(
66 "got opcode {got:?}, expected {expected:?}"
67 )));
68 }
69 Ok(got)
70 }
71}
72
73#[derive(Debug, PartialEq)]
75pub struct RemoteScanStoppedOperation;
76
77impl ControlPointOperation for RemoteScanStoppedOperation {
78 fn opcode() -> ControlPointOpcode {
79 ControlPointOpcode::RemoteScanStopped
80 }
81}
82
83impl Decodable for RemoteScanStoppedOperation {
84 type Error = PacketError;
85
86 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
87 const BYTE_SIZE: usize = ControlPointOpcode::BYTE_SIZE;
88 if buf.len() < BYTE_SIZE {
89 return (Err(PacketError::BufferTooSmall), buf.len());
90 }
91 (Self::check_opcode(buf[0]).map(|_| RemoteScanStoppedOperation), BYTE_SIZE)
92 }
93}
94
95impl Encodable for RemoteScanStoppedOperation {
96 type Error = PacketError;
97
98 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
99 if buf.len() < self.encoded_len() {
100 return Err(PacketError::BufferTooSmall);
101 }
102 buf[0] = Self::opcode() as u8;
103 Ok(())
104 }
105
106 fn encoded_len(&self) -> core::primitive::usize {
107 ControlPointOpcode::BYTE_SIZE
108 }
109}
110
111#[derive(Debug, PartialEq)]
113pub struct RemoteScanStartedOperation;
114
115impl ControlPointOperation for RemoteScanStartedOperation {
116 fn opcode() -> ControlPointOpcode {
117 ControlPointOpcode::RemoteScanStarted
118 }
119}
120
121impl Decodable for RemoteScanStartedOperation {
122 type Error = PacketError;
123
124 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
125 const BYTE_SIZE: usize = ControlPointOpcode::BYTE_SIZE;
126 if buf.len() < BYTE_SIZE {
127 return (Err(PacketError::UnexpectedDataLength), buf.len());
128 }
129 (Self::check_opcode(buf[0]).map(|_| RemoteScanStartedOperation), BYTE_SIZE)
130 }
131}
132
133impl Encodable for RemoteScanStartedOperation {
134 type Error = PacketError;
135
136 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
137 if buf.len() < self.encoded_len() {
138 return Err(PacketError::BufferTooSmall);
139 }
140 buf[0] = Self::opcode() as u8;
141 Ok(())
142 }
143
144 fn encoded_len(&self) -> core::primitive::usize {
145 ControlPointOpcode::BYTE_SIZE
146 }
147}
148
149#[derive(Debug, PartialEq)]
151pub struct AddSourceOperation {
152 pub(crate) advertiser_address_type: AddressType,
153 pub(crate) advertiser_address: [u8; ADDRESS_BYTE_SIZE],
155 pub(crate) advertising_sid: AdvertisingSetId,
156 pub(crate) broadcast_id: BroadcastId,
157 pub(crate) pa_sync: PaSync,
158 pub(crate) pa_interval: PeriodicAdvertisingInterval,
159 pub(crate) subgroups: Vec<BigSubgroup>,
160}
161
162impl AddSourceOperation {
163 const MIN_PACKET_SIZE: usize = ControlPointOpcode::BYTE_SIZE
164 + AddressType::BYTE_SIZE
165 + ADDRESS_BYTE_SIZE
166 + AdvertisingSetId::BYTE_SIZE
167 + BroadcastId::BYTE_SIZE
168 + PA_SYNC_BYTE_SIZE
169 + PeriodicAdvertisingInterval::BYTE_SIZE
170 + NUM_SUBGROUPS_BYTE_SIZE;
171
172 pub fn new(
173 address_type: AddressType,
174 advertiser_address: [u8; ADDRESS_BYTE_SIZE],
175 advertising_sid: AdvertisingSetId,
176 broadcast_id: BroadcastId,
177 pa_sync: PaSync,
178 pa_interval: PeriodicAdvertisingInterval,
179 subgroups: Vec<BigSubgroup>,
180 ) -> Self {
181 AddSourceOperation {
182 advertiser_address_type: address_type,
183 advertiser_address,
184 advertising_sid,
185 broadcast_id: broadcast_id,
186 pa_sync,
187 pa_interval,
188 subgroups,
189 }
190 }
191}
192
193impl ControlPointOperation for AddSourceOperation {
194 fn opcode() -> ControlPointOpcode {
195 ControlPointOpcode::AddSource
196 }
197}
198
199impl Decodable for AddSourceOperation {
200 type Error = PacketError;
201
202 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
203 if buf.len() < Self::MIN_PACKET_SIZE {
204 return (Err(PacketError::UnexpectedDataLength), buf.len());
205 }
206
207 let decode_fn = || {
208 let _ = Self::check_opcode(buf[0])?;
209 let advertiser_address_type = AddressType::try_from(buf[1])?;
210 let mut advertiser_address = [0; ADDRESS_BYTE_SIZE];
211 advertiser_address.clone_from_slice(&buf[2..8]);
212 let advertising_sid = AdvertisingSetId(buf[8]);
213 let broadcast_id = BroadcastId::decode(&buf[9..12]).0?;
214 let pa_sync = PaSync::try_from(buf[12])?;
215 let pa_interval =
216 PeriodicAdvertisingInterval(u16::from_le_bytes(buf[13..15].try_into().unwrap()));
217 let num_subgroups = buf[15] as usize;
218 let mut subgroups = Vec::new();
219
220 let mut idx: usize = 16;
221 for _i in 0..num_subgroups {
222 if buf.len() <= idx {
223 return Err(PacketError::UnexpectedDataLength);
224 }
225 let (decoded, consumed) = BigSubgroup::decode(&buf[idx..]);
226 subgroups.push(decoded?);
227 idx += consumed;
228 }
229 Ok((
230 Self {
231 advertiser_address_type,
232 advertiser_address,
233 advertising_sid,
234 broadcast_id,
235 pa_sync,
236 pa_interval,
237 subgroups,
238 },
239 idx,
240 ))
241 };
242
243 match decode_fn() {
244 Ok((result, consumed)) => (Ok(result), consumed),
245 Err(e) => (Err(e), buf.len()),
246 }
247 }
248}
249
250impl Encodable for AddSourceOperation {
251 type Error = PacketError;
252
253 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
254 if buf.len() < self.encoded_len() {
255 return Err(PacketError::BufferTooSmall);
256 }
257
258 buf[0] = Self::opcode() as u8;
259 buf[1] = self.advertiser_address_type as u8;
260 buf[2..8].copy_from_slice(&self.advertiser_address);
261 buf[8] = self.advertising_sid.0;
262 self.broadcast_id.encode(&mut buf[9..12])?;
263 buf[12] = u8::from(self.pa_sync);
264 buf[13..15].copy_from_slice(&self.pa_interval.0.to_le_bytes());
265 buf[15] = self
266 .subgroups
267 .len()
268 .try_into()
269 .map_err(|_| PacketError::InvalidParameter("Num_Subgroups".to_string()))?;
270 let mut idx = 16;
271 for s in &self.subgroups {
272 s.encode(&mut buf[idx..])?;
273 idx += s.encoded_len();
274 }
275 Ok(())
276 }
277
278 fn encoded_len(&self) -> core::primitive::usize {
279 Self::MIN_PACKET_SIZE + self.subgroups.iter().fold(0, |acc, g| acc + g.encoded_len())
280 }
281}
282
283#[derive(Debug, PartialEq)]
285pub struct ModifySourceOperation {
286 source_id: SourceId,
287 pa_sync: PaSync,
288 pa_interval: PeriodicAdvertisingInterval,
289 subgroups: Vec<BigSubgroup>,
290}
291
292impl ModifySourceOperation {
293 const MIN_PACKET_SIZE: usize = ControlPointOpcode::BYTE_SIZE
294 + SOURCE_ID_BYTE_SIZE
295 + PA_SYNC_BYTE_SIZE
296 + PeriodicAdvertisingInterval::BYTE_SIZE
297 + NUM_SUBGROUPS_BYTE_SIZE;
298
299 pub fn new(
300 source_id: SourceId,
301 pa_sync: PaSync,
302 pa_interval: PeriodicAdvertisingInterval,
303 subgroups: Vec<BigSubgroup>,
304 ) -> Self {
305 ModifySourceOperation { source_id, pa_sync, pa_interval, subgroups }
306 }
307}
308
309impl ControlPointOperation for ModifySourceOperation {
310 fn opcode() -> ControlPointOpcode {
311 ControlPointOpcode::ModifySource
312 }
313}
314
315impl Decodable for ModifySourceOperation {
316 type Error = PacketError;
317
318 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
320 if buf.len() < Self::MIN_PACKET_SIZE {
321 return (Err(PacketError::UnexpectedDataLength), buf.len());
322 }
323 let decode_fn = || {
324 let _ = Self::check_opcode(buf[0])?;
325 let source_id = buf[1];
326 let pa_sync = PaSync::try_from(buf[2])?;
327 let pa_interval =
328 PeriodicAdvertisingInterval(u16::from_le_bytes(buf[3..5].try_into().unwrap()));
329 let num_subgroups = buf[5] as usize;
330 let mut subgroups = Vec::new();
331
332 let mut idx = 6;
333 for _i in 0..num_subgroups {
334 if buf.len() < idx + BigSubgroup::MIN_PACKET_SIZE {
335 return Err(PacketError::UnexpectedDataLength);
336 }
337 let decoded = BigSubgroup::decode(&buf[idx..]);
338 subgroups.push(decoded.0?);
339 idx += decoded.1;
340 }
341 Ok((Self { source_id, pa_sync, pa_interval, subgroups }, idx))
342 };
343
344 match decode_fn() {
345 Ok((obj, consumed)) => (Ok(obj), consumed),
346 Err(e) => (Err(e), buf.len()),
347 }
348 }
349}
350
351impl Encodable for ModifySourceOperation {
352 type Error = PacketError;
353
354 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
355 if buf.len() < self.encoded_len() {
356 return Err(PacketError::BufferTooSmall);
357 }
358
359 buf[0] = Self::opcode() as u8;
360 buf[1] = self.source_id;
361 buf[2] = u8::from(self.pa_sync);
362 buf[3..5].copy_from_slice(&self.pa_interval.0.to_le_bytes());
363 buf[5] = self
364 .subgroups
365 .len()
366 .try_into()
367 .map_err(|_| PacketError::InvalidParameter("Num_Subgroups".to_string()))?;
368 let mut idx = 6;
369 for s in &self.subgroups {
370 s.encode(&mut buf[idx..])?;
371 idx += s.encoded_len();
372 }
373 Ok(())
374 }
375
376 fn encoded_len(&self) -> core::primitive::usize {
377 Self::MIN_PACKET_SIZE + self.subgroups.iter().fold(0, |acc, g| acc + g.encoded_len())
378 }
379}
380
381#[derive(Debug, PartialEq)]
383pub struct SetBroadcastCodeOperation {
384 source_id: SourceId,
385 broadcast_code: [u8; 16],
386}
387
388impl SetBroadcastCodeOperation {
389 const BROADCAST_CODE_LEN: usize = 16;
390 const PACKET_SIZE: usize =
391 ControlPointOpcode::BYTE_SIZE + SOURCE_ID_BYTE_SIZE + Self::BROADCAST_CODE_LEN;
392
393 pub fn new(source_id: SourceId, broadcast_code: [u8; 16]) -> Self {
394 SetBroadcastCodeOperation { source_id, broadcast_code }
395 }
396}
397
398impl ControlPointOperation for SetBroadcastCodeOperation {
399 fn opcode() -> ControlPointOpcode {
400 ControlPointOpcode::SetBroadcastCode
401 }
402}
403
404impl Decodable for SetBroadcastCodeOperation {
405 type Error = PacketError;
406
407 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
409 if buf.len() < Self::PACKET_SIZE {
410 return (Err(PacketError::UnexpectedDataLength), buf.len());
411 }
412 let decode_fn = || {
413 let _ = Self::check_opcode(buf[0])?;
414 let source_id = buf[1];
415 let mut broadcast_code = [0; Self::BROADCAST_CODE_LEN];
416 broadcast_code.copy_from_slice(&buf[2..2 + Self::BROADCAST_CODE_LEN]);
417 Ok((Self { source_id, broadcast_code }, Self::PACKET_SIZE))
418 };
419
420 match decode_fn() {
421 Ok((obj, consumed)) => (Ok(obj), consumed),
422 Err(e) => (Err(e), buf.len()),
423 }
424 }
425}
426
427impl Encodable for SetBroadcastCodeOperation {
428 type Error = PacketError;
429
430 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
431 if buf.len() < self.encoded_len() {
432 return Err(PacketError::BufferTooSmall);
433 }
434
435 buf[0] = Self::opcode() as u8;
436 buf[1] = self.source_id;
437 buf[2..2 + Self::BROADCAST_CODE_LEN].copy_from_slice(&self.broadcast_code);
438 Ok(())
439 }
440
441 fn encoded_len(&self) -> core::primitive::usize {
442 Self::PACKET_SIZE
443 }
444}
445
446#[derive(Debug, PartialEq)]
448pub struct RemoveSourceOperation(SourceId);
449
450impl RemoveSourceOperation {
451 const PACKET_SIZE: usize = ControlPointOpcode::BYTE_SIZE + SOURCE_ID_BYTE_SIZE;
452
453 pub fn new(source_id: SourceId) -> Self {
454 RemoveSourceOperation(source_id)
455 }
456}
457
458impl ControlPointOperation for RemoveSourceOperation {
459 fn opcode() -> ControlPointOpcode {
460 ControlPointOpcode::RemoveSource
461 }
462}
463
464impl Decodable for RemoveSourceOperation {
465 type Error = PacketError;
466
467 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
469 if buf.len() < Self::PACKET_SIZE {
470 return (Err(PacketError::UnexpectedDataLength), buf.len());
471 }
472 let decode_fn = || {
473 let _ = Self::check_opcode(buf[0])?;
474 let source_id = buf[1];
475 Ok((RemoveSourceOperation(source_id), Self::PACKET_SIZE))
476 };
477 match decode_fn() {
478 Ok((obj, consumed)) => (Ok(obj), consumed),
479 Err(e) => (Err(e), buf.len()),
480 }
481 }
482}
483
484impl Encodable for RemoveSourceOperation {
485 type Error = PacketError;
486
487 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
488 if buf.len() < self.encoded_len() {
489 return Err(PacketError::BufferTooSmall);
490 }
491
492 buf[0] = Self::opcode() as u8;
493 buf[1] = self.0;
494 Ok(())
495 }
496
497 fn encoded_len(&self) -> core::primitive::usize {
498 Self::PACKET_SIZE
499 }
500}
501
502decodable_enum! {
503 pub enum PaSync<u8, bt_common::packet_encoding::Error, OutOfRange> {
504 DoNotSync = 0x00,
505 SyncPastAvailable = 0x01,
506 SyncPastUnavailable = 0x02,
507 }
508}
509
510impl FromStr for PaSync {
511 type Err = PacketError;
512
513 fn from_str(s: &str) -> Result<Self, Self::Err> {
514 match s {
515 "PaSyncOff" => Ok(PaSync::DoNotSync),
516 "PaSyncPast" => Ok(PaSync::SyncPastAvailable),
517 "PaSyncNoPast" => Ok(PaSync::SyncPastUnavailable),
518 _ => Err(PacketError::InvalidParameter(format!("invalid pa_sync: {s}"))),
519 }
520 }
521}
522
523#[derive(Clone, Debug, PartialEq)]
529pub struct BisSync(u32);
530
531impl BisSync {
532 const BYTE_SIZE: usize = 4;
533 const NO_PREFERENCE: u32 = 0xFFFFFFFF;
534
535 pub fn no_sync() -> BisSync {
537 BisSync(0)
538 }
539
540 pub fn synchronize_to_index(&mut self, bis_index: BisIndex) -> Result<(), PacketError> {
548 if bis_index < 1 || bis_index > 31 {
549 return Err(PacketError::OutOfRange);
550 }
551 let bit_mask = 0b1 << (bis_index - 1);
552
553 self.0 &= !(0b1 << bis_index - 1);
555 self.0 |= bit_mask;
556 Ok(())
557 }
558
559 pub fn sync(bis_indices: Vec<BisIndex>) -> Result<Self, PacketError> {
566 let mut new_sync = Self::no_sync();
567 for bis_index in bis_indices {
568 new_sync.synchronize_to_index(bis_index)?;
569 }
570 Ok(new_sync)
571 }
572}
573
574impl Default for BisSync {
575 fn default() -> Self {
576 Self(Self::NO_PREFERENCE)
577 }
578}
579
580impl From<BisSync> for u32 {
581 fn from(bis_sync: BisSync) -> u32 {
582 bis_sync.0
583 }
584}
585
586#[derive(Clone, Debug, PartialEq)]
587pub struct BigSubgroup {
588 pub(crate) bis_sync: BisSync,
589 pub(crate) metadata: Vec<Metadata>,
590}
591
592impl BigSubgroup {
593 const METADATA_LENGTH_BYTE_SIZE: usize = 1;
594 const MIN_PACKET_SIZE: usize = BisSync::BYTE_SIZE + Self::METADATA_LENGTH_BYTE_SIZE;
595
596 pub fn new(bis_sync: Option<BisSync>) -> Self {
597 Self { bis_sync: bis_sync.unwrap_or_default(), metadata: vec![] }
598 }
599
600 pub fn with_metadata(mut self, metadata: Vec<Metadata>) -> Self {
601 self.metadata = metadata;
602 self
603 }
604}
605
606impl Decodable for BigSubgroup {
607 type Error = PacketError;
608
609 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
610 if buf.len() < BigSubgroup::MIN_PACKET_SIZE {
611 return (Err(PacketError::UnexpectedDataLength), buf.len());
612 }
613 let decode_fn = || {
614 let bis_sync = u32::from_le_bytes(buf[0..4].try_into().unwrap());
615 let metadata_len = buf[4] as usize;
616
617 let mut start_idx = 5;
618 if buf.len() < start_idx + metadata_len {
619 return Err(PacketError::UnexpectedDataLength);
620 }
621
622 let (results_metadata, consumed_len) =
623 Metadata::decode_all(&buf[start_idx..start_idx + metadata_len]);
624 start_idx += consumed_len;
625 if start_idx != 5 + metadata_len {
626 return Err(PacketError::UnexpectedDataLength);
627 }
628 let metadata = results_metadata.into_iter().filter_map(Result::ok).collect();
630 Ok((BigSubgroup { bis_sync: BisSync(bis_sync), metadata }, start_idx))
631 };
632 match decode_fn() {
633 Ok((obj, consumed)) => (Ok(obj), consumed),
634 Err(e) => (Err(e), buf.len()),
635 }
636 }
637}
638
639impl Encodable for BigSubgroup {
640 type Error = PacketError;
641
642 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
643 if buf.len() < self.encoded_len() {
644 return Err(PacketError::BufferTooSmall);
645 }
646
647 buf[0..4].copy_from_slice(&u32::from(self.bis_sync.clone()).to_le_bytes());
648 let metadata_len = self
649 .metadata
650 .iter()
651 .fold(0, |acc, m| acc + m.encoded_len())
652 .try_into()
653 .map_err(|_| PacketError::InvalidParameter("Metadata".to_string()))?;
654 buf[4] = metadata_len;
655 let mut next_idx = 5;
656 for m in &self.metadata {
657 m.encode(&mut buf[next_idx..])
658 .map_err(|e| PacketError::InvalidParameter(format!("{e}")))?;
659 next_idx += m.encoded_len();
660 }
661 Ok(())
662 }
663
664 fn encoded_len(&self) -> core::primitive::usize {
665 Self::MIN_PACKET_SIZE + self.metadata.iter().map(Encodable::encoded_len).sum::<usize>()
666 }
667}
668
669#[derive(Clone, Debug, PartialEq)]
676pub enum BroadcastReceiveState {
677 Empty,
678 NonEmpty(ReceiveState),
679}
680
681impl BroadcastReceiveState {
682 pub fn is_empty(&self) -> bool {
683 *self == BroadcastReceiveState::Empty
684 }
685
686 pub fn broadcast_id(&self) -> Option<BroadcastId> {
687 match self {
688 BroadcastReceiveState::Empty => None,
689 BroadcastReceiveState::NonEmpty(state) => Some(state.broadcast_id),
690 }
691 }
692
693 pub fn has_same_broadcast_id(&self, other: &BroadcastReceiveState) -> bool {
694 match self {
695 BroadcastReceiveState::Empty => false,
696 BroadcastReceiveState::NonEmpty(this) => match other {
697 BroadcastReceiveState::Empty => false,
698 BroadcastReceiveState::NonEmpty(that) => this.broadcast_id == that.broadcast_id,
699 },
700 }
701 }
702}
703
704impl Decodable for BroadcastReceiveState {
705 type Error = PacketError;
706
707 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
708 if buf.len() == 0 {
709 return (Ok(Self::Empty), 0);
710 }
711 match ReceiveState::decode(&buf[..]) {
712 (Ok(state), consumed) => (Ok(Self::NonEmpty(state)), consumed),
713 (Err(e), consumed) => (Err(e), consumed),
714 }
715 }
716}
717
718impl Encodable for BroadcastReceiveState {
719 type Error = PacketError;
720
721 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
722 match self {
723 Self::Empty => Ok(()),
724 Self::NonEmpty(state) => state.encode(&mut buf[..]),
725 }
726 }
727
728 fn encoded_len(&self) -> core::primitive::usize {
729 match self {
730 Self::Empty => 0,
731 Self::NonEmpty(state) => state.encoded_len(),
732 }
733 }
734}
735
736#[derive(Clone, Debug, PartialEq)]
737pub struct ReceiveState {
738 pub(crate) source_id: SourceId,
739 pub(crate) source_address_type: AddressType,
740 pub(crate) source_address: [u8; ADDRESS_BYTE_SIZE],
742 pub(crate) source_adv_sid: AdvertisingSetId,
743 pub(crate) broadcast_id: BroadcastId,
744 pub(crate) pa_sync_state: PaSyncState,
745 pub(crate) big_encryption: EncryptionStatus,
747 pub(crate) subgroups: Vec<BigSubgroup>,
748}
749
750impl ReceiveState {
751 const MIN_PACKET_SIZE: usize = SOURCE_ID_BYTE_SIZE
752 + AddressType::BYTE_SIZE
753 + ADDRESS_BYTE_SIZE
754 + AdvertisingSetId::BYTE_SIZE
755 + BroadcastId::BYTE_SIZE
756 + PA_SYNC_BYTE_SIZE
757 + EncryptionStatus::MIN_PACKET_SIZE
758 + NUM_SUBGROUPS_BYTE_SIZE;
759
760 #[cfg(any(test, feature = "test-utils"))]
761 pub fn new(
762 source_id: u8,
763 source_address_type: AddressType,
764 source_address: [u8; ADDRESS_BYTE_SIZE],
765 source_adv_sid: u8,
766 broadcast_id: BroadcastId,
767 pa_sync_state: PaSyncState,
768 big_encryption: EncryptionStatus,
769 subgroups: Vec<BigSubgroup>,
770 ) -> ReceiveState {
771 Self {
772 source_id,
773 source_address_type,
774 source_address,
775 source_adv_sid: AdvertisingSetId(source_adv_sid),
776 broadcast_id,
777 pa_sync_state,
778 big_encryption,
779 subgroups,
780 }
781 }
782
783 pub fn pa_sync_state(&self) -> PaSyncState {
784 self.pa_sync_state
785 }
786
787 pub fn big_encryption(&self) -> EncryptionStatus {
788 self.big_encryption
789 }
790
791 pub fn broadcast_id(&self) -> BroadcastId {
792 self.broadcast_id
793 }
794
795 pub fn source_id(&self) -> SourceId {
796 self.source_id
797 }
798}
799
800impl Decodable for ReceiveState {
801 type Error = PacketError;
802
803 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
804 if buf.len() < Self::MIN_PACKET_SIZE {
805 return (Err(PacketError::UnexpectedDataLength), buf.len());
806 }
807
808 let decode_fn = || {
809 let source_id = buf[0];
810 let source_address_type = AddressType::try_from(buf[1])?;
811 let mut source_address = [0; ADDRESS_BYTE_SIZE];
812 source_address.clone_from_slice(&buf[2..8]);
813 let source_adv_sid = AdvertisingSetId(buf[8]);
814 let broadcast_id = BroadcastId::decode(&buf[9..12]).0?;
815 let pa_sync_state = PaSyncState::try_from(buf[12])?;
816
817 let big_encryption;
818 let mut idx = 13;
819 match EncryptionStatus::decode(&buf[13..]) {
820 (Ok(encryption), consumed) => {
821 big_encryption = encryption;
822 idx += consumed;
823 }
824 (Err(e), _) => {
825 return Err(e);
826 }
827 }
828 if buf.len() <= idx {
829 return Err(PacketError::UnexpectedDataLength);
830 }
831 let num_subgroups = buf[idx] as usize;
832 let mut subgroups = Vec::new();
833 idx += 1;
834 for _i in 0..num_subgroups {
835 if buf.len() <= idx {
836 return Err(PacketError::UnexpectedDataLength);
837 }
838 let (subgroup, consumed) = BigSubgroup::decode(&buf[idx..]);
839 subgroups.push(subgroup?);
840 idx += consumed;
841 }
842 Ok((
843 ReceiveState {
844 source_id,
845 source_address_type,
846 source_address,
847 source_adv_sid,
848 broadcast_id,
849 pa_sync_state,
850 big_encryption,
851 subgroups,
852 },
853 idx,
854 ))
855 };
856 match decode_fn() {
857 Ok((obj, consumed)) => (Ok(obj), consumed),
858 Err(e) => (Err(e), buf.len()),
859 }
860 }
861}
862
863impl Encodable for ReceiveState {
864 type Error = PacketError;
865
866 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
867 if buf.len() < self.encoded_len() {
868 return Err(PacketError::BufferTooSmall);
869 }
870
871 buf[0] = self.source_id;
872 buf[1] = self.source_address_type as u8;
873 buf[2..8].copy_from_slice(&self.source_address);
874 buf[8] = self.source_adv_sid.0;
875 self.broadcast_id.encode(&mut buf[9..12])?;
876 buf[12] = u8::from(self.pa_sync_state);
877 let mut idx = 13 + self.big_encryption.encoded_len();
878 self.big_encryption.encode(&mut buf[13..idx])?;
879 buf[idx] = self
880 .subgroups
881 .len()
882 .try_into()
883 .map_err(|_| PacketError::InvalidParameter("Metadata".to_string()))?;
884 idx += 1;
885 for s in &self.subgroups {
886 s.encode(&mut buf[idx..])?;
887 idx += s.encoded_len();
888 }
889 Ok(())
890 }
891
892 fn encoded_len(&self) -> core::primitive::usize {
893 SOURCE_ID_BYTE_SIZE
897 + AddressType::BYTE_SIZE
898 + self.source_address.len()
899 + AdvertisingSetId::BYTE_SIZE
900 + self.broadcast_id.encoded_len()
901 + PA_SYNC_BYTE_SIZE
902 + self.big_encryption.encoded_len()
903 + NUM_SUBGROUPS_BYTE_SIZE
904 + self.subgroups.iter().map(Encodable::encoded_len).sum::<usize>()
905 }
906}
907
908decodable_enum! {
909 pub enum PaSyncState<u8, bt_common::packet_encoding::Error, OutOfRange> {
910 NotSynced = 0x00,
911 SyncInfoRequest = 0x01,
912 Synced = 0x02,
913 FailedToSync = 0x03,
914 NoPast = 0x04,
915 }
916}
917
918#[derive(Clone, Copy, Debug, PartialEq)]
921pub enum EncryptionStatus {
922 NotEncrypted,
923 BroadcastCodeRequired,
924 Decrypting,
925 BadCode([u8; 16]),
926}
927
928impl EncryptionStatus {
929 const MIN_PACKET_SIZE: usize = 1;
931
932 pub const fn raw_value(self) -> u8 {
935 match self {
936 EncryptionStatus::NotEncrypted => 0x00,
937 EncryptionStatus::BroadcastCodeRequired => 0x01,
938 EncryptionStatus::Decrypting => 0x02,
939 EncryptionStatus::BadCode(_) => 0x03,
940 }
941 }
942}
943
944impl Decodable for EncryptionStatus {
945 type Error = PacketError;
946
947 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
948 if buf.len() < 1 {
949 return (Err(PacketError::UnexpectedDataLength), buf.len());
950 }
951 match buf[0] {
952 0x00 => (Ok(Self::NotEncrypted), 1),
953 0x01 => (Ok(Self::BroadcastCodeRequired), 1),
954 0x02 => (Ok(Self::Decrypting), 1),
955 0x03 => {
956 if buf.len() < 17 {
957 return (Err(PacketError::UnexpectedDataLength), buf.len());
958 }
959 (Ok(Self::BadCode(buf[1..17].try_into().unwrap())), 17)
960 }
961 _ => (Err(PacketError::OutOfRange), buf.len()),
962 }
963 }
964}
965
966impl Encodable for EncryptionStatus {
967 type Error = PacketError;
968
969 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
970 if buf.len() < self.encoded_len() {
971 return Err(PacketError::BufferTooSmall);
972 }
973
974 buf[0] = self.raw_value();
975 match self {
976 EncryptionStatus::BadCode(code) => buf[1..17].copy_from_slice(code),
977 _ => {}
978 }
979 Ok(())
980 }
981
982 fn encoded_len(&self) -> core::primitive::usize {
983 match self {
984 EncryptionStatus::BadCode(_) => 1 + 16,
987 _ => 1,
988 }
989 }
990}
991
992#[cfg(test)]
993mod tests {
994 use super::*;
995
996 use bt_common::generic_audio::ContextType;
997
998 #[test]
999 fn encryption_status_enum() {
1000 let not_encrypted = EncryptionStatus::NotEncrypted;
1001 let encrypted = EncryptionStatus::BroadcastCodeRequired;
1002 let decrypting = EncryptionStatus::Decrypting;
1003 let bad_code = EncryptionStatus::BadCode([
1004 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
1005 0x02, 0x01,
1006 ]);
1007
1008 assert_eq!(0x00, not_encrypted.raw_value());
1009 assert_eq!(0x01, encrypted.raw_value());
1010 assert_eq!(0x02, decrypting.raw_value());
1011 assert_eq!(0x03, bad_code.raw_value());
1012 }
1013
1014 #[test]
1015 fn encryption_status() {
1016 let not_encrypted = EncryptionStatus::NotEncrypted;
1018 assert_eq!(not_encrypted.encoded_len(), 1);
1019 let mut buf = vec![0; not_encrypted.encoded_len()];
1020 let _ = not_encrypted.encode(&mut buf[..]).expect("should not fail");
1021
1022 let bytes = vec![0x00];
1023 assert_eq!(buf, bytes);
1024
1025 let (decoded, len) = EncryptionStatus::decode(&bytes);
1027 assert_eq!(decoded, Ok(not_encrypted));
1028 assert_eq!(len, 1);
1029
1030 let bad_code = EncryptionStatus::BadCode([
1032 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
1033 0x02, 0x01,
1034 ]);
1035 assert_eq!(bad_code.encoded_len(), 17);
1036 let mut buf = vec![0; bad_code.encoded_len()];
1037 let _ = bad_code.encode(&mut buf[..]).expect("should not fail");
1038
1039 let bytes = vec![
1040 0x03, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04,
1041 0x03, 0x02, 0x01,
1042 ];
1043 assert_eq!(buf, bytes);
1044
1045 let (decoded, len) = EncryptionStatus::decode(&bytes);
1047 assert_eq!(decoded, Ok(bad_code));
1048 assert_eq!(len, 17);
1049 }
1050
1051 #[test]
1052 fn invalid_encryption_status() {
1053 let not_encrypted = EncryptionStatus::NotEncrypted;
1055 let mut buf = vec![];
1056 let _ = not_encrypted.encode(&mut buf[..]).expect_err("should fail");
1057
1058 let bad_code = EncryptionStatus::BadCode([
1060 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
1061 0x02, 0x01,
1062 ]);
1063 let mut buf = vec![0; 1];
1064 let _ = bad_code.encode(&mut buf[..]).expect_err("should fail");
1065
1066 let buf = vec![];
1068 let _ = EncryptionStatus::decode(&buf).0.expect_err("should fail");
1069
1070 let buf = vec![0x03];
1072 let _ = EncryptionStatus::decode(&buf).0.expect_err("should fail");
1073 }
1074
1075 #[test]
1076 fn bis_sync_sync() {
1077 let bis_sync = BisSync::sync(vec![1, 6, 31]).expect("should succeed");
1078 assert_eq!(u32::from(bis_sync), 0x40000021);
1079
1080 let bis_sync_empty = BisSync::sync(vec![]).expect("should succeed");
1081 assert_eq!(u32::from(bis_sync_empty), 0);
1082 }
1083
1084 #[test]
1085 fn invalid_bis_sync() {
1086 BisSync::sync(vec![0]).expect_err("should fail");
1087 BisSync::sync(vec![32]).expect_err("should fail");
1088 }
1089
1090 #[test]
1091 fn synchronize_to_index() {
1092 let mut bis_sync = BisSync::no_sync();
1093 assert_eq!(u32::from(bis_sync.clone()), 0);
1094
1095 bis_sync.synchronize_to_index(1).expect("should succeed");
1096 assert_eq!(u32::from(bis_sync.clone()), 0x1);
1097
1098 bis_sync.synchronize_to_index(31).expect("should succeed");
1099 assert_eq!(u32::from(bis_sync.clone()), 0x40000001);
1100
1101 bis_sync.synchronize_to_index(0).expect_err("should fail");
1102 bis_sync.synchronize_to_index(32).expect_err("should fail");
1103 }
1104
1105 #[test]
1106 fn pa_sync_from_str() {
1107 let sync = PaSync::from_str("PaSyncOff").expect("should succeed");
1108 assert_eq!(sync, PaSync::DoNotSync);
1109 let sync = PaSync::from_str("PaSyncPast").expect("should succeed");
1110 assert_eq!(sync, PaSync::SyncPastAvailable);
1111 let sync = PaSync::from_str("PaSyncNoPast").expect("should succeed");
1112 assert_eq!(sync, PaSync::SyncPastUnavailable);
1113 PaSync::from_str("invalid").expect_err("should fail");
1114 }
1115
1116 #[test]
1117 fn remote_scan_stopped() {
1118 let stopped = RemoteScanStoppedOperation;
1120 assert_eq!(stopped.encoded_len(), 1);
1121 let mut buf = vec![0u8; stopped.encoded_len()];
1122 stopped.encode(&mut buf[..]).expect("shoud succeed");
1123
1124 let bytes = vec![0x00];
1125 assert_eq!(buf, bytes);
1126
1127 let (decoded, len) = RemoteScanStoppedOperation::decode(&bytes);
1129 assert_eq!(decoded, Ok(stopped));
1130 assert_eq!(len, 1);
1131 }
1132
1133 #[test]
1134 fn remote_scan_started() {
1135 let started = RemoteScanStartedOperation;
1137 assert_eq!(started.encoded_len(), 1);
1138 let mut buf = vec![0u8; started.encoded_len()];
1139 started.encode(&mut buf[..]).expect("shoud succeed");
1140
1141 let bytes = vec![0x01];
1142 assert_eq!(buf, vec![0x01]);
1143
1144 let (decoded, len) = RemoteScanStartedOperation::decode(&bytes);
1146 assert_eq!(decoded, Ok(started));
1147 assert_eq!(len, 1);
1148 }
1149
1150 #[test]
1151 fn add_source_without_subgroups() {
1152 let op = AddSourceOperation::new(
1154 AddressType::Public,
1155 [0x04, 0x10, 0x00, 0x00, 0x00, 0x00],
1156 AdvertisingSetId(1),
1157 BroadcastId::try_from(0x11).unwrap(),
1158 PaSync::DoNotSync,
1159 PeriodicAdvertisingInterval::unknown(),
1160 vec![],
1161 );
1162 assert_eq!(op.encoded_len(), 16);
1163 let mut buf = vec![0u8; op.encoded_len()];
1164 op.encode(&mut buf[..]).expect("shoud succeed");
1165
1166 let bytes = vec![
1167 0x02, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0xFF,
1168 0xFF, 0x00,
1169 ];
1170 assert_eq!(buf, bytes);
1171
1172 let (decoded, len) = AddSourceOperation::decode(&bytes);
1174 assert_eq!(decoded, Ok(op));
1175 assert_eq!(len, 16);
1176 }
1177
1178 #[test]
1179 fn add_source_with_subgroups() {
1180 let subgroups = vec![BigSubgroup::new(None).with_metadata(vec![
1182 Metadata::PreferredAudioContexts(vec![ContextType::Media, ContextType::Game]), Metadata::ProgramInfo("test".to_string()), ])];
1185 let op = AddSourceOperation::new(
1186 AddressType::Random,
1187 [0x04, 0x10, 0x00, 0x00, 0x00, 0x00],
1188 AdvertisingSetId(1),
1189 BroadcastId::try_from(0x11).unwrap(),
1190 PaSync::SyncPastAvailable,
1191 PeriodicAdvertisingInterval::unknown(),
1192 subgroups,
1193 );
1194 assert_eq!(op.encoded_len(), 31); let mut buf = vec![0u8; op.encoded_len()];
1196 op.encode(&mut buf[..]).expect("shoud succeed");
1197
1198 let bytes = vec![
1199 0x02, 0x01, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x01, 0xFF,
1200 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x03, 0x01, 0x0C, 0x00, 0x05, 0x03, 0x74, 0x65, 0x73, 0x074, ];
1204 assert_eq!(buf, bytes);
1205
1206 let (decoded, len) = AddSourceOperation::decode(&bytes);
1208 assert_eq!(decoded, Ok(op));
1209 assert_eq!(len, 31);
1210 }
1211
1212 #[test]
1213 fn modify_source_without_subgroups() {
1214 let op = ModifySourceOperation::new(
1216 0x0A,
1217 PaSync::SyncPastAvailable,
1218 PeriodicAdvertisingInterval(0x1004),
1219 vec![],
1220 );
1221 assert_eq!(op.encoded_len(), 6);
1222 let mut buf = vec![0u8; op.encoded_len()];
1223 op.encode(&mut buf[..]).expect("shoud succeed");
1224
1225 let bytes = vec![0x03, 0x0A, 0x01, 0x04, 0x10, 0x00];
1226 assert_eq!(buf, bytes);
1227
1228 let (decoded, len) = ModifySourceOperation::decode(&bytes);
1230 assert_eq!(decoded, Ok(op));
1231 assert_eq!(len, 6);
1232 }
1233
1234 #[test]
1235 fn modify_source_with_subgroups() {
1236 let subgroups = vec![
1238 BigSubgroup::new(None).with_metadata(vec![Metadata::ParentalRating(Rating::all_age())]), BigSubgroup::new(Some(BisSync(0x000000FE)))
1240 .with_metadata(vec![Metadata::BroadcastAudioImmediateRenderingFlag]), ];
1242 let op = ModifySourceOperation::new(
1243 0x0B,
1244 PaSync::DoNotSync,
1245 PeriodicAdvertisingInterval::unknown(),
1246 subgroups,
1247 );
1248 assert_eq!(op.encoded_len(), 21); let mut buf = vec![0u8; op.encoded_len()];
1250 op.encode(&mut buf[..]).expect("shoud succeed");
1251
1252 let bytes = vec![
1253 0x03, 0x0B, 0x00, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x02, 0x06,
1254 0x01, 0xFE, 0x00, 0x00, 0x00, 0x02, 0x01, 0x09, ];
1257 assert_eq!(buf, bytes);
1258
1259 let (decoded, len) = ModifySourceOperation::decode(&bytes);
1261 assert_eq!(decoded, Ok(op));
1262 assert_eq!(len, 21);
1263 }
1264
1265 #[test]
1266 fn set_broadcast_code() {
1267 let op = SetBroadcastCodeOperation::new(
1269 0x0A,
1270 [
1271 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14,
1272 0x15, 0x16,
1273 ],
1274 );
1275 assert_eq!(op.encoded_len(), 18);
1276 let mut buf = vec![0; op.encoded_len()];
1277 op.encode(&mut buf[..]).expect("should succeed");
1278
1279 let bytes = vec![
1280 0x04, 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12,
1281 0x13, 0x14, 0x15, 0x16,
1282 ];
1283 assert_eq!(buf, bytes);
1284
1285 let (decoded, len) = SetBroadcastCodeOperation::decode(&bytes);
1287 assert_eq!(decoded, Ok(op));
1288 assert_eq!(len, 18);
1289 }
1290
1291 #[test]
1292 fn remove_source() {
1293 let op = RemoveSourceOperation::new(0x0A);
1295 assert_eq!(op.encoded_len(), 2);
1296 let mut buf = vec![0; op.encoded_len()];
1297 op.encode(&mut buf[..]).expect("should succeed");
1298
1299 let bytes = vec![0x05, 0x0A];
1300 assert_eq!(buf, bytes);
1301
1302 let (decoded, len) = RemoveSourceOperation::decode(&bytes);
1304 assert_eq!(decoded, Ok(op));
1305 assert_eq!(len, 2);
1306 }
1307
1308 #[test]
1309 fn broadcast_receive_state_without_subgroups() {
1310 let state = BroadcastReceiveState::NonEmpty(ReceiveState {
1312 source_id: 0x01,
1313 source_address_type: AddressType::Public,
1314 source_address: [0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A],
1315 source_adv_sid: AdvertisingSetId(0x01),
1316 broadcast_id: BroadcastId::try_from(0x00010203).unwrap(),
1317 pa_sync_state: PaSyncState::Synced,
1318 big_encryption: EncryptionStatus::BadCode([
1319 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x7, 0x06, 0x05, 0x04, 0x03,
1320 0x02, 0x01,
1321 ]),
1322 subgroups: vec![],
1323 });
1324 assert_eq!(state.encoded_len(), 31);
1325 let mut buf = vec![0; state.encoded_len()];
1326 state.encode(&mut buf[..]).expect("should succeed");
1327
1328 let bytes = vec![
1329 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x01, 0x03, 0x02, 0x01, 0x02, 0x03,
1330 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
1331 0x02, 0x01, 0x00,
1333 ];
1334 assert_eq!(buf, bytes);
1335
1336 let (decoded, len) = BroadcastReceiveState::decode(&bytes);
1338 assert_eq!(decoded, Ok(state));
1339 assert_eq!(len, 31);
1340 }
1341
1342 #[test]
1343 fn broadcast_receive_state_with_subgroups() {
1344 let state = BroadcastReceiveState::NonEmpty(ReceiveState {
1346 source_id: 0x01,
1347 source_address_type: AddressType::Random,
1348 source_address: [0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A],
1349 source_adv_sid: AdvertisingSetId(0x01),
1350 broadcast_id: BroadcastId::try_from(0x00010203).unwrap(),
1351 pa_sync_state: PaSyncState::NotSynced,
1352 big_encryption: EncryptionStatus::NotEncrypted,
1353 subgroups: vec![BigSubgroup::new(None)
1354 .with_metadata(vec![Metadata::ParentalRating(Rating::AllAge)]) ],
1355 });
1356 assert_eq!(state.encoded_len(), 23);
1357 let mut buf = vec![0; state.encoded_len()];
1358 state.encode(&mut buf[..]).expect("should succeed");
1359
1360 let bytes = vec![
1361 0x01, 0x01, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x01, 0x03, 0x02, 0x01, 0x00, 0x00,
1362 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x02, 0x06, 0x01, ];
1365 assert_eq!(buf, bytes);
1366
1367 let (decoded, len) = BroadcastReceiveState::decode(&bytes);
1369 assert_eq!(decoded, Ok(state));
1370 assert_eq!(len, 23);
1371 }
1372}