1use bt_bap::types::BroadcastId;
6use bt_common::core::ltv::LtValue;
7use bt_common::core::{AddressType, AdvertisingSetId, PaInterval};
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: PaInterval,
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 + PaInterval::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: PaInterval,
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 = PaInterval(u16::from_le_bytes(buf[13..15].try_into().unwrap()));
216 let num_subgroups = buf[15] as usize;
217 let mut subgroups = Vec::new();
218
219 let mut idx: usize = 16;
220 for _i in 0..num_subgroups {
221 if buf.len() <= idx {
222 return Err(PacketError::UnexpectedDataLength);
223 }
224 let (decoded, consumed) = BigSubgroup::decode(&buf[idx..]);
225 subgroups.push(decoded?);
226 idx += consumed;
227 }
228 Ok((
229 Self {
230 advertiser_address_type,
231 advertiser_address,
232 advertising_sid,
233 broadcast_id,
234 pa_sync,
235 pa_interval,
236 subgroups,
237 },
238 idx,
239 ))
240 };
241
242 match decode_fn() {
243 Ok((result, consumed)) => (Ok(result), consumed),
244 Err(e) => (Err(e), buf.len()),
245 }
246 }
247}
248
249impl Encodable for AddSourceOperation {
250 type Error = PacketError;
251
252 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
253 if buf.len() < self.encoded_len() {
254 return Err(PacketError::BufferTooSmall);
255 }
256
257 buf[0] = Self::opcode() as u8;
258 buf[1] = self.advertiser_address_type as u8;
259 buf[2..8].copy_from_slice(&self.advertiser_address);
260 buf[8] = self.advertising_sid.0;
261 self.broadcast_id.encode(&mut buf[9..12])?;
262 buf[12] = u8::from(self.pa_sync);
263 buf[13..15].copy_from_slice(&self.pa_interval.0.to_le_bytes());
264 buf[15] = self
265 .subgroups
266 .len()
267 .try_into()
268 .map_err(|_| PacketError::InvalidParameter("Num_Subgroups".to_string()))?;
269 let mut idx = 16;
270 for s in &self.subgroups {
271 s.encode(&mut buf[idx..])?;
272 idx += s.encoded_len();
273 }
274 Ok(())
275 }
276
277 fn encoded_len(&self) -> core::primitive::usize {
278 Self::MIN_PACKET_SIZE + self.subgroups.iter().fold(0, |acc, g| acc + g.encoded_len())
279 }
280}
281
282#[derive(Debug, PartialEq)]
284pub struct ModifySourceOperation {
285 source_id: SourceId,
286 pa_sync: PaSync,
287 pa_interval: PaInterval,
288 subgroups: Vec<BigSubgroup>,
289}
290
291impl ModifySourceOperation {
292 const MIN_PACKET_SIZE: usize = ControlPointOpcode::BYTE_SIZE
293 + SOURCE_ID_BYTE_SIZE
294 + PA_SYNC_BYTE_SIZE
295 + PaInterval::BYTE_SIZE
296 + NUM_SUBGROUPS_BYTE_SIZE;
297
298 pub fn new(
299 source_id: SourceId,
300 pa_sync: PaSync,
301 pa_interval: PaInterval,
302 subgroups: Vec<BigSubgroup>,
303 ) -> Self {
304 ModifySourceOperation { source_id, pa_sync, pa_interval, subgroups }
305 }
306}
307
308impl ControlPointOperation for ModifySourceOperation {
309 fn opcode() -> ControlPointOpcode {
310 ControlPointOpcode::ModifySource
311 }
312}
313
314impl Decodable for ModifySourceOperation {
315 type Error = PacketError;
316
317 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
319 if buf.len() < Self::MIN_PACKET_SIZE {
320 return (Err(PacketError::UnexpectedDataLength), buf.len());
321 }
322 let decode_fn = || {
323 let _ = Self::check_opcode(buf[0])?;
324 let source_id = buf[1];
325 let pa_sync = PaSync::try_from(buf[2])?;
326 let pa_interval = PaInterval(u16::from_le_bytes(buf[3..5].try_into().unwrap()));
327 let num_subgroups = buf[5] as usize;
328 let mut subgroups = Vec::new();
329
330 let mut idx = 6;
331 for _i in 0..num_subgroups {
332 if buf.len() < idx + BigSubgroup::MIN_PACKET_SIZE {
333 return Err(PacketError::UnexpectedDataLength);
334 }
335 let decoded = BigSubgroup::decode(&buf[idx..]);
336 subgroups.push(decoded.0?);
337 idx += decoded.1;
338 }
339 Ok((Self { source_id, pa_sync, pa_interval, subgroups }, idx))
340 };
341
342 match decode_fn() {
343 Ok((obj, consumed)) => (Ok(obj), consumed),
344 Err(e) => (Err(e), buf.len()),
345 }
346 }
347}
348
349impl Encodable for ModifySourceOperation {
350 type Error = PacketError;
351
352 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
353 if buf.len() < self.encoded_len() {
354 return Err(PacketError::BufferTooSmall);
355 }
356
357 buf[0] = Self::opcode() as u8;
358 buf[1] = self.source_id;
359 buf[2] = u8::from(self.pa_sync);
360 buf[3..5].copy_from_slice(&self.pa_interval.0.to_le_bytes());
361 buf[5] = self
362 .subgroups
363 .len()
364 .try_into()
365 .map_err(|_| PacketError::InvalidParameter("Num_Subgroups".to_string()))?;
366 let mut idx = 6;
367 for s in &self.subgroups {
368 s.encode(&mut buf[idx..])?;
369 idx += s.encoded_len();
370 }
371 Ok(())
372 }
373
374 fn encoded_len(&self) -> core::primitive::usize {
375 Self::MIN_PACKET_SIZE + self.subgroups.iter().fold(0, |acc, g| acc + g.encoded_len())
376 }
377}
378
379#[derive(Debug, PartialEq)]
381pub struct SetBroadcastCodeOperation {
382 source_id: SourceId,
383 broadcast_code: [u8; 16],
384}
385
386impl SetBroadcastCodeOperation {
387 const BROADCAST_CODE_LEN: usize = 16;
388 const PACKET_SIZE: usize =
389 ControlPointOpcode::BYTE_SIZE + SOURCE_ID_BYTE_SIZE + Self::BROADCAST_CODE_LEN;
390
391 pub fn new(source_id: SourceId, broadcast_code: [u8; 16]) -> Self {
392 SetBroadcastCodeOperation { source_id, broadcast_code }
393 }
394}
395
396impl ControlPointOperation for SetBroadcastCodeOperation {
397 fn opcode() -> ControlPointOpcode {
398 ControlPointOpcode::SetBroadcastCode
399 }
400}
401
402impl Decodable for SetBroadcastCodeOperation {
403 type Error = PacketError;
404
405 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
407 if buf.len() < Self::PACKET_SIZE {
408 return (Err(PacketError::UnexpectedDataLength), buf.len());
409 }
410 let decode_fn = || {
411 let _ = Self::check_opcode(buf[0])?;
412 let source_id = buf[1];
413 let mut broadcast_code = [0; Self::BROADCAST_CODE_LEN];
414 broadcast_code.copy_from_slice(&buf[2..2 + Self::BROADCAST_CODE_LEN]);
415 Ok((Self { source_id, broadcast_code }, Self::PACKET_SIZE))
416 };
417
418 match decode_fn() {
419 Ok((obj, consumed)) => (Ok(obj), consumed),
420 Err(e) => (Err(e), buf.len()),
421 }
422 }
423}
424
425impl Encodable for SetBroadcastCodeOperation {
426 type Error = PacketError;
427
428 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
429 if buf.len() < self.encoded_len() {
430 return Err(PacketError::BufferTooSmall);
431 }
432
433 buf[0] = Self::opcode() as u8;
434 buf[1] = self.source_id;
435 buf[2..2 + Self::BROADCAST_CODE_LEN].copy_from_slice(&self.broadcast_code);
436 Ok(())
437 }
438
439 fn encoded_len(&self) -> core::primitive::usize {
440 Self::PACKET_SIZE
441 }
442}
443
444#[derive(Debug, PartialEq)]
446pub struct RemoveSourceOperation(SourceId);
447
448impl RemoveSourceOperation {
449 const PACKET_SIZE: usize = ControlPointOpcode::BYTE_SIZE + SOURCE_ID_BYTE_SIZE;
450
451 pub fn new(source_id: SourceId) -> Self {
452 RemoveSourceOperation(source_id)
453 }
454}
455
456impl ControlPointOperation for RemoveSourceOperation {
457 fn opcode() -> ControlPointOpcode {
458 ControlPointOpcode::RemoveSource
459 }
460}
461
462impl Decodable for RemoveSourceOperation {
463 type Error = PacketError;
464
465 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
467 if buf.len() < Self::PACKET_SIZE {
468 return (Err(PacketError::UnexpectedDataLength), buf.len());
469 }
470 let decode_fn = || {
471 let _ = Self::check_opcode(buf[0])?;
472 let source_id = buf[1];
473 Ok((RemoveSourceOperation(source_id), Self::PACKET_SIZE))
474 };
475 match decode_fn() {
476 Ok((obj, consumed)) => (Ok(obj), consumed),
477 Err(e) => (Err(e), buf.len()),
478 }
479 }
480}
481
482impl Encodable for RemoveSourceOperation {
483 type Error = PacketError;
484
485 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
486 if buf.len() < self.encoded_len() {
487 return Err(PacketError::BufferTooSmall);
488 }
489
490 buf[0] = Self::opcode() as u8;
491 buf[1] = self.0;
492 Ok(())
493 }
494
495 fn encoded_len(&self) -> core::primitive::usize {
496 Self::PACKET_SIZE
497 }
498}
499
500decodable_enum! {
501 pub enum PaSync<u8, bt_common::packet_encoding::Error, OutOfRange> {
502 DoNotSync = 0x00,
503 SyncPastAvailable = 0x01,
504 SyncPastUnavailable = 0x02,
505 }
506}
507
508impl FromStr for PaSync {
509 type Err = PacketError;
510
511 fn from_str(s: &str) -> Result<Self, Self::Err> {
512 match s {
513 "PaSyncOff" => Ok(PaSync::DoNotSync),
514 "PaSyncPast" => Ok(PaSync::SyncPastAvailable),
515 "PaSyncNoPast" => Ok(PaSync::SyncPastUnavailable),
516 _ => Err(PacketError::InvalidParameter(format!("invalid pa_sync: {s}"))),
517 }
518 }
519}
520
521#[derive(Clone, Debug, PartialEq)]
527pub struct BisSync(u32);
528
529impl BisSync {
530 const BYTE_SIZE: usize = 4;
531 const NO_PREFERENCE: u32 = 0xFFFFFFFF;
532
533 pub fn no_sync() -> BisSync {
535 BisSync(0)
536 }
537
538 pub fn synchronize_to_index(&mut self, bis_index: BisIndex) -> Result<(), PacketError> {
546 if bis_index < 1 || bis_index > 31 {
547 return Err(PacketError::OutOfRange);
548 }
549 let bit_mask = 0b1 << (bis_index - 1);
550
551 self.0 &= !(0b1 << bis_index - 1);
553 self.0 |= bit_mask;
554 Ok(())
555 }
556
557 pub fn sync(bis_indices: Vec<BisIndex>) -> Result<Self, PacketError> {
564 let mut new_sync = Self::no_sync();
565 for bis_index in bis_indices {
566 new_sync.synchronize_to_index(bis_index)?;
567 }
568 Ok(new_sync)
569 }
570}
571
572impl Default for BisSync {
573 fn default() -> Self {
574 Self(Self::NO_PREFERENCE)
575 }
576}
577
578impl From<BisSync> for u32 {
579 fn from(bis_sync: BisSync) -> u32 {
580 bis_sync.0
581 }
582}
583
584#[derive(Clone, Debug, PartialEq)]
585pub struct BigSubgroup {
586 pub(crate) bis_sync: BisSync,
587 pub(crate) metadata: Vec<Metadata>,
588}
589
590impl BigSubgroup {
591 const METADATA_LENGTH_BYTE_SIZE: usize = 1;
592 const MIN_PACKET_SIZE: usize = BisSync::BYTE_SIZE + Self::METADATA_LENGTH_BYTE_SIZE;
593
594 pub fn new(bis_sync: Option<BisSync>) -> Self {
595 Self { bis_sync: bis_sync.unwrap_or_default(), metadata: vec![] }
596 }
597
598 pub fn with_metadata(mut self, metadata: Vec<Metadata>) -> Self {
599 self.metadata = metadata;
600 self
601 }
602}
603
604impl Decodable for BigSubgroup {
605 type Error = PacketError;
606
607 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
608 if buf.len() < BigSubgroup::MIN_PACKET_SIZE {
609 return (Err(PacketError::UnexpectedDataLength), buf.len());
610 }
611 let decode_fn = || {
612 let bis_sync = u32::from_le_bytes(buf[0..4].try_into().unwrap());
613 let metadata_len = buf[4] as usize;
614
615 let mut start_idx = 5;
616 if buf.len() < start_idx + metadata_len {
617 return Err(PacketError::UnexpectedDataLength);
618 }
619
620 let (results_metadata, consumed_len) =
621 Metadata::decode_all(&buf[start_idx..start_idx + metadata_len]);
622 start_idx += consumed_len;
623 if start_idx != 5 + metadata_len {
624 return Err(PacketError::UnexpectedDataLength);
625 }
626 let metadata = results_metadata.into_iter().filter_map(Result::ok).collect();
628 Ok((BigSubgroup { bis_sync: BisSync(bis_sync), metadata }, start_idx))
629 };
630 match decode_fn() {
631 Ok((obj, consumed)) => (Ok(obj), consumed),
632 Err(e) => (Err(e), buf.len()),
633 }
634 }
635}
636
637impl Encodable for BigSubgroup {
638 type Error = PacketError;
639
640 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
641 if buf.len() < self.encoded_len() {
642 return Err(PacketError::BufferTooSmall);
643 }
644
645 buf[0..4].copy_from_slice(&u32::from(self.bis_sync.clone()).to_le_bytes());
646 let metadata_len = self
647 .metadata
648 .iter()
649 .fold(0, |acc, m| acc + m.encoded_len())
650 .try_into()
651 .map_err(|_| PacketError::InvalidParameter("Metadata".to_string()))?;
652 buf[4] = metadata_len;
653 let mut next_idx = 5;
654 for m in &self.metadata {
655 m.encode(&mut buf[next_idx..])
656 .map_err(|e| PacketError::InvalidParameter(format!("{e}")))?;
657 next_idx += m.encoded_len();
658 }
659 Ok(())
660 }
661
662 fn encoded_len(&self) -> core::primitive::usize {
663 Self::MIN_PACKET_SIZE + self.metadata.iter().map(Encodable::encoded_len).sum::<usize>()
664 }
665}
666
667#[derive(Clone, Debug, PartialEq)]
674pub enum BroadcastReceiveState {
675 Empty,
676 NonEmpty(ReceiveState),
677}
678
679impl BroadcastReceiveState {
680 pub fn is_empty(&self) -> bool {
681 *self == BroadcastReceiveState::Empty
682 }
683
684 pub fn broadcast_id(&self) -> Option<BroadcastId> {
685 match self {
686 BroadcastReceiveState::Empty => None,
687 BroadcastReceiveState::NonEmpty(state) => Some(state.broadcast_id),
688 }
689 }
690
691 pub fn has_same_broadcast_id(&self, other: &BroadcastReceiveState) -> bool {
692 match self {
693 BroadcastReceiveState::Empty => false,
694 BroadcastReceiveState::NonEmpty(this) => match other {
695 BroadcastReceiveState::Empty => false,
696 BroadcastReceiveState::NonEmpty(that) => this.broadcast_id == that.broadcast_id,
697 },
698 }
699 }
700}
701
702impl Decodable for BroadcastReceiveState {
703 type Error = PacketError;
704
705 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
706 if buf.len() == 0 {
707 return (Ok(Self::Empty), 0);
708 }
709 match ReceiveState::decode(&buf[..]) {
710 (Ok(state), consumed) => (Ok(Self::NonEmpty(state)), consumed),
711 (Err(e), consumed) => (Err(e), consumed),
712 }
713 }
714}
715
716impl Encodable for BroadcastReceiveState {
717 type Error = PacketError;
718
719 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
720 match self {
721 Self::Empty => Ok(()),
722 Self::NonEmpty(state) => state.encode(&mut buf[..]),
723 }
724 }
725
726 fn encoded_len(&self) -> core::primitive::usize {
727 match self {
728 Self::Empty => 0,
729 Self::NonEmpty(state) => state.encoded_len(),
730 }
731 }
732}
733
734#[derive(Clone, Debug, PartialEq)]
735pub struct ReceiveState {
736 pub(crate) source_id: SourceId,
737 pub(crate) source_address_type: AddressType,
738 pub(crate) source_address: [u8; ADDRESS_BYTE_SIZE],
740 pub(crate) source_adv_sid: AdvertisingSetId,
741 pub(crate) broadcast_id: BroadcastId,
742 pub(crate) pa_sync_state: PaSyncState,
743 pub(crate) big_encryption: EncryptionStatus,
745 pub(crate) subgroups: Vec<BigSubgroup>,
746}
747
748impl ReceiveState {
749 const MIN_PACKET_SIZE: usize = SOURCE_ID_BYTE_SIZE
750 + AddressType::BYTE_SIZE
751 + ADDRESS_BYTE_SIZE
752 + AdvertisingSetId::BYTE_SIZE
753 + BroadcastId::BYTE_SIZE
754 + PA_SYNC_BYTE_SIZE
755 + EncryptionStatus::MIN_PACKET_SIZE
756 + NUM_SUBGROUPS_BYTE_SIZE;
757
758 #[cfg(any(test, feature = "test-utils"))]
759 pub fn new(
760 source_id: u8,
761 source_address_type: AddressType,
762 source_address: [u8; ADDRESS_BYTE_SIZE],
763 source_adv_sid: u8,
764 broadcast_id: BroadcastId,
765 pa_sync_state: PaSyncState,
766 big_encryption: EncryptionStatus,
767 subgroups: Vec<BigSubgroup>,
768 ) -> ReceiveState {
769 Self {
770 source_id,
771 source_address_type,
772 source_address,
773 source_adv_sid: AdvertisingSetId(source_adv_sid),
774 broadcast_id,
775 pa_sync_state,
776 big_encryption,
777 subgroups,
778 }
779 }
780
781 pub fn pa_sync_state(&self) -> PaSyncState {
782 self.pa_sync_state
783 }
784
785 pub fn big_encryption(&self) -> EncryptionStatus {
786 self.big_encryption
787 }
788
789 pub fn broadcast_id(&self) -> BroadcastId {
790 self.broadcast_id
791 }
792
793 pub fn source_id(&self) -> SourceId {
794 self.source_id
795 }
796}
797
798impl Decodable for ReceiveState {
799 type Error = PacketError;
800
801 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
802 if buf.len() < Self::MIN_PACKET_SIZE {
803 return (Err(PacketError::UnexpectedDataLength), buf.len());
804 }
805
806 let decode_fn = || {
807 let source_id = buf[0];
808 let source_address_type = AddressType::try_from(buf[1])?;
809 let mut source_address = [0; ADDRESS_BYTE_SIZE];
810 source_address.clone_from_slice(&buf[2..8]);
811 let source_adv_sid = AdvertisingSetId(buf[8]);
812 let broadcast_id = BroadcastId::decode(&buf[9..12]).0?;
813 let pa_sync_state = PaSyncState::try_from(buf[12])?;
814
815 let big_encryption;
816 let mut idx = 13;
817 match EncryptionStatus::decode(&buf[13..]) {
818 (Ok(encryption), consumed) => {
819 big_encryption = encryption;
820 idx += consumed;
821 }
822 (Err(e), _) => {
823 return Err(e);
824 }
825 }
826 if buf.len() <= idx {
827 return Err(PacketError::UnexpectedDataLength);
828 }
829 let num_subgroups = buf[idx] as usize;
830 let mut subgroups = Vec::new();
831 idx += 1;
832 for _i in 0..num_subgroups {
833 if buf.len() <= idx {
834 return Err(PacketError::UnexpectedDataLength);
835 }
836 let (subgroup, consumed) = BigSubgroup::decode(&buf[idx..]);
837 subgroups.push(subgroup?);
838 idx += consumed;
839 }
840 Ok((
841 ReceiveState {
842 source_id,
843 source_address_type,
844 source_address,
845 source_adv_sid,
846 broadcast_id,
847 pa_sync_state,
848 big_encryption,
849 subgroups,
850 },
851 idx,
852 ))
853 };
854 match decode_fn() {
855 Ok((obj, consumed)) => (Ok(obj), consumed),
856 Err(e) => (Err(e), buf.len()),
857 }
858 }
859}
860
861impl Encodable for ReceiveState {
862 type Error = PacketError;
863
864 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
865 if buf.len() < self.encoded_len() {
866 return Err(PacketError::BufferTooSmall);
867 }
868
869 buf[0] = self.source_id;
870 buf[1] = self.source_address_type as u8;
871 buf[2..8].copy_from_slice(&self.source_address);
872 buf[8] = self.source_adv_sid.0;
873 self.broadcast_id.encode(&mut buf[9..12])?;
874 buf[12] = u8::from(self.pa_sync_state);
875 let mut idx = 13 + self.big_encryption.encoded_len();
876 self.big_encryption.encode(&mut buf[13..idx])?;
877 buf[idx] = self
878 .subgroups
879 .len()
880 .try_into()
881 .map_err(|_| PacketError::InvalidParameter("Metadata".to_string()))?;
882 idx += 1;
883 for s in &self.subgroups {
884 s.encode(&mut buf[idx..])?;
885 idx += s.encoded_len();
886 }
887 Ok(())
888 }
889
890 fn encoded_len(&self) -> core::primitive::usize {
891 SOURCE_ID_BYTE_SIZE
895 + AddressType::BYTE_SIZE
896 + self.source_address.len()
897 + AdvertisingSetId::BYTE_SIZE
898 + self.broadcast_id.encoded_len()
899 + PA_SYNC_BYTE_SIZE
900 + self.big_encryption.encoded_len()
901 + NUM_SUBGROUPS_BYTE_SIZE
902 + self.subgroups.iter().map(Encodable::encoded_len).sum::<usize>()
903 }
904}
905
906decodable_enum! {
907 pub enum PaSyncState<u8, bt_common::packet_encoding::Error, OutOfRange> {
908 NotSynced = 0x00,
909 SyncInfoRequest = 0x01,
910 Synced = 0x02,
911 FailedToSync = 0x03,
912 NoPast = 0x04,
913 }
914}
915
916#[derive(Clone, Copy, Debug, PartialEq)]
919pub enum EncryptionStatus {
920 NotEncrypted,
921 BroadcastCodeRequired,
922 Decrypting,
923 BadCode([u8; 16]),
924}
925
926impl EncryptionStatus {
927 const MIN_PACKET_SIZE: usize = 1;
929
930 pub const fn raw_value(self) -> u8 {
933 match self {
934 EncryptionStatus::NotEncrypted => 0x00,
935 EncryptionStatus::BroadcastCodeRequired => 0x01,
936 EncryptionStatus::Decrypting => 0x02,
937 EncryptionStatus::BadCode(_) => 0x03,
938 }
939 }
940}
941
942impl Decodable for EncryptionStatus {
943 type Error = PacketError;
944
945 fn decode(buf: &[u8]) -> (core::result::Result<Self, Self::Error>, usize) {
946 if buf.len() < 1 {
947 return (Err(PacketError::UnexpectedDataLength), buf.len());
948 }
949 match buf[0] {
950 0x00 => (Ok(Self::NotEncrypted), 1),
951 0x01 => (Ok(Self::BroadcastCodeRequired), 1),
952 0x02 => (Ok(Self::Decrypting), 1),
953 0x03 => {
954 if buf.len() < 17 {
955 return (Err(PacketError::UnexpectedDataLength), buf.len());
956 }
957 (Ok(Self::BadCode(buf[1..17].try_into().unwrap())), 17)
958 }
959 _ => (Err(PacketError::OutOfRange), buf.len()),
960 }
961 }
962}
963
964impl Encodable for EncryptionStatus {
965 type Error = PacketError;
966
967 fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
968 if buf.len() < self.encoded_len() {
969 return Err(PacketError::BufferTooSmall);
970 }
971
972 buf[0] = self.raw_value();
973 match self {
974 EncryptionStatus::BadCode(code) => buf[1..17].copy_from_slice(code),
975 _ => {}
976 }
977 Ok(())
978 }
979
980 fn encoded_len(&self) -> core::primitive::usize {
981 match self {
982 EncryptionStatus::BadCode(_) => 1 + 16,
985 _ => 1,
986 }
987 }
988}
989
990#[cfg(test)]
991mod tests {
992 use super::*;
993
994 use bt_common::generic_audio::ContextType;
995
996 #[test]
997 fn encryption_status_enum() {
998 let not_encrypted = EncryptionStatus::NotEncrypted;
999 let encrypted = EncryptionStatus::BroadcastCodeRequired;
1000 let decrypting = EncryptionStatus::Decrypting;
1001 let bad_code = EncryptionStatus::BadCode([
1002 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
1003 0x02, 0x01,
1004 ]);
1005
1006 assert_eq!(0x00, not_encrypted.raw_value());
1007 assert_eq!(0x01, encrypted.raw_value());
1008 assert_eq!(0x02, decrypting.raw_value());
1009 assert_eq!(0x03, bad_code.raw_value());
1010 }
1011
1012 #[test]
1013 fn encryption_status() {
1014 let not_encrypted = EncryptionStatus::NotEncrypted;
1016 assert_eq!(not_encrypted.encoded_len(), 1);
1017 let mut buf = vec![0; not_encrypted.encoded_len()];
1018 let _ = not_encrypted.encode(&mut buf[..]).expect("should not fail");
1019
1020 let bytes = vec![0x00];
1021 assert_eq!(buf, bytes);
1022
1023 let (decoded, len) = EncryptionStatus::decode(&bytes);
1025 assert_eq!(decoded, Ok(not_encrypted));
1026 assert_eq!(len, 1);
1027
1028 let bad_code = EncryptionStatus::BadCode([
1030 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
1031 0x02, 0x01,
1032 ]);
1033 assert_eq!(bad_code.encoded_len(), 17);
1034 let mut buf = vec![0; bad_code.encoded_len()];
1035 let _ = bad_code.encode(&mut buf[..]).expect("should not fail");
1036
1037 let bytes = vec![
1038 0x03, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04,
1039 0x03, 0x02, 0x01,
1040 ];
1041 assert_eq!(buf, bytes);
1042
1043 let (decoded, len) = EncryptionStatus::decode(&bytes);
1045 assert_eq!(decoded, Ok(bad_code));
1046 assert_eq!(len, 17);
1047 }
1048
1049 #[test]
1050 fn invalid_encryption_status() {
1051 let not_encrypted = EncryptionStatus::NotEncrypted;
1053 let mut buf = vec![];
1054 let _ = not_encrypted.encode(&mut buf[..]).expect_err("should fail");
1055
1056 let bad_code = EncryptionStatus::BadCode([
1058 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
1059 0x02, 0x01,
1060 ]);
1061 let mut buf = vec![0; 1];
1062 let _ = bad_code.encode(&mut buf[..]).expect_err("should fail");
1063
1064 let buf = vec![];
1066 let _ = EncryptionStatus::decode(&buf).0.expect_err("should fail");
1067
1068 let buf = vec![0x03];
1070 let _ = EncryptionStatus::decode(&buf).0.expect_err("should fail");
1071 }
1072
1073 #[test]
1074 fn bis_sync_sync() {
1075 let bis_sync = BisSync::sync(vec![1, 6, 31]).expect("should succeed");
1076 assert_eq!(u32::from(bis_sync), 0x40000021);
1077
1078 let bis_sync_empty = BisSync::sync(vec![]).expect("should succeed");
1079 assert_eq!(u32::from(bis_sync_empty), 0);
1080 }
1081
1082 #[test]
1083 fn invalid_bis_sync() {
1084 BisSync::sync(vec![0]).expect_err("should fail");
1085 BisSync::sync(vec![32]).expect_err("should fail");
1086 }
1087
1088 #[test]
1089 fn synchronize_to_index() {
1090 let mut bis_sync = BisSync::no_sync();
1091 assert_eq!(u32::from(bis_sync.clone()), 0);
1092
1093 bis_sync.synchronize_to_index(1).expect("should succeed");
1094 assert_eq!(u32::from(bis_sync.clone()), 0x1);
1095
1096 bis_sync.synchronize_to_index(31).expect("should succeed");
1097 assert_eq!(u32::from(bis_sync.clone()), 0x40000001);
1098
1099 bis_sync.synchronize_to_index(0).expect_err("should fail");
1100 bis_sync.synchronize_to_index(32).expect_err("should fail");
1101 }
1102
1103 #[test]
1104 fn pa_sync_from_str() {
1105 let sync = PaSync::from_str("PaSyncOff").expect("should succeed");
1106 assert_eq!(sync, PaSync::DoNotSync);
1107 let sync = PaSync::from_str("PaSyncPast").expect("should succeed");
1108 assert_eq!(sync, PaSync::SyncPastAvailable);
1109 let sync = PaSync::from_str("PaSyncNoPast").expect("should succeed");
1110 assert_eq!(sync, PaSync::SyncPastUnavailable);
1111 PaSync::from_str("invalid").expect_err("should fail");
1112 }
1113
1114 #[test]
1115 fn remote_scan_stopped() {
1116 let stopped = RemoteScanStoppedOperation;
1118 assert_eq!(stopped.encoded_len(), 1);
1119 let mut buf = vec![0u8; stopped.encoded_len()];
1120 stopped.encode(&mut buf[..]).expect("shoud succeed");
1121
1122 let bytes = vec![0x00];
1123 assert_eq!(buf, bytes);
1124
1125 let (decoded, len) = RemoteScanStoppedOperation::decode(&bytes);
1127 assert_eq!(decoded, Ok(stopped));
1128 assert_eq!(len, 1);
1129 }
1130
1131 #[test]
1132 fn remote_scan_started() {
1133 let started = RemoteScanStartedOperation;
1135 assert_eq!(started.encoded_len(), 1);
1136 let mut buf = vec![0u8; started.encoded_len()];
1137 started.encode(&mut buf[..]).expect("shoud succeed");
1138
1139 let bytes = vec![0x01];
1140 assert_eq!(buf, vec![0x01]);
1141
1142 let (decoded, len) = RemoteScanStartedOperation::decode(&bytes);
1144 assert_eq!(decoded, Ok(started));
1145 assert_eq!(len, 1);
1146 }
1147
1148 #[test]
1149 fn add_source_without_subgroups() {
1150 let op = AddSourceOperation::new(
1152 AddressType::Public,
1153 [0x04, 0x10, 0x00, 0x00, 0x00, 0x00],
1154 AdvertisingSetId(1),
1155 BroadcastId::try_from(0x11).unwrap(),
1156 PaSync::DoNotSync,
1157 PaInterval::unknown(),
1158 vec![],
1159 );
1160 assert_eq!(op.encoded_len(), 16);
1161 let mut buf = vec![0u8; op.encoded_len()];
1162 op.encode(&mut buf[..]).expect("shoud succeed");
1163
1164 let bytes = vec![
1165 0x02, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0xFF,
1166 0xFF, 0x00,
1167 ];
1168 assert_eq!(buf, bytes);
1169
1170 let (decoded, len) = AddSourceOperation::decode(&bytes);
1172 assert_eq!(decoded, Ok(op));
1173 assert_eq!(len, 16);
1174 }
1175
1176 #[test]
1177 fn add_source_with_subgroups() {
1178 let subgroups = vec![BigSubgroup::new(None).with_metadata(vec![
1180 Metadata::PreferredAudioContexts(vec![ContextType::Media, ContextType::Game]), Metadata::ProgramInfo("test".to_string()), ])];
1183 let op = AddSourceOperation::new(
1184 AddressType::Random,
1185 [0x04, 0x10, 0x00, 0x00, 0x00, 0x00],
1186 AdvertisingSetId(1),
1187 BroadcastId::try_from(0x11).unwrap(),
1188 PaSync::SyncPastAvailable,
1189 PaInterval::unknown(),
1190 subgroups,
1191 );
1192 assert_eq!(op.encoded_len(), 31); let mut buf = vec![0u8; op.encoded_len()];
1194 op.encode(&mut buf[..]).expect("shoud succeed");
1195
1196 let bytes = vec![
1197 0x02, 0x01, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x01, 0xFF,
1198 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x03, 0x01, 0x0C, 0x00, 0x05, 0x03, 0x74, 0x65, 0x73, 0x074, ];
1202 assert_eq!(buf, bytes);
1203
1204 let (decoded, len) = AddSourceOperation::decode(&bytes);
1206 assert_eq!(decoded, Ok(op));
1207 assert_eq!(len, 31);
1208 }
1209
1210 #[test]
1211 fn modify_source_without_subgroups() {
1212 let op =
1214 ModifySourceOperation::new(0x0A, PaSync::SyncPastAvailable, PaInterval(0x1004), vec![]);
1215 assert_eq!(op.encoded_len(), 6);
1216 let mut buf = vec![0u8; op.encoded_len()];
1217 op.encode(&mut buf[..]).expect("shoud succeed");
1218
1219 let bytes = vec![0x03, 0x0A, 0x01, 0x04, 0x10, 0x00];
1220 assert_eq!(buf, bytes);
1221
1222 let (decoded, len) = ModifySourceOperation::decode(&bytes);
1224 assert_eq!(decoded, Ok(op));
1225 assert_eq!(len, 6);
1226 }
1227
1228 #[test]
1229 fn modify_source_with_subgroups() {
1230 let subgroups = vec![
1232 BigSubgroup::new(None).with_metadata(vec![Metadata::ParentalRating(Rating::all_age())]), BigSubgroup::new(Some(BisSync(0x000000FE)))
1234 .with_metadata(vec![Metadata::BroadcastAudioImmediateRenderingFlag]), ];
1236 let op =
1237 ModifySourceOperation::new(0x0B, PaSync::DoNotSync, PaInterval::unknown(), subgroups);
1238 assert_eq!(op.encoded_len(), 21); let mut buf = vec![0u8; op.encoded_len()];
1240 op.encode(&mut buf[..]).expect("shoud succeed");
1241
1242 let bytes = vec![
1243 0x03, 0x0B, 0x00, 0xFF, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x02, 0x06,
1244 0x01, 0xFE, 0x00, 0x00, 0x00, 0x02, 0x01, 0x09, ];
1247 assert_eq!(buf, bytes);
1248
1249 let (decoded, len) = ModifySourceOperation::decode(&bytes);
1251 assert_eq!(decoded, Ok(op));
1252 assert_eq!(len, 21);
1253 }
1254
1255 #[test]
1256 fn set_broadcast_code() {
1257 let op = SetBroadcastCodeOperation::new(
1259 0x0A,
1260 [
1261 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14,
1262 0x15, 0x16,
1263 ],
1264 );
1265 assert_eq!(op.encoded_len(), 18);
1266 let mut buf = vec![0; op.encoded_len()];
1267 op.encode(&mut buf[..]).expect("should succeed");
1268
1269 let bytes = vec![
1270 0x04, 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12,
1271 0x13, 0x14, 0x15, 0x16,
1272 ];
1273 assert_eq!(buf, bytes);
1274
1275 let (decoded, len) = SetBroadcastCodeOperation::decode(&bytes);
1277 assert_eq!(decoded, Ok(op));
1278 assert_eq!(len, 18);
1279 }
1280
1281 #[test]
1282 fn remove_source() {
1283 let op = RemoveSourceOperation::new(0x0A);
1285 assert_eq!(op.encoded_len(), 2);
1286 let mut buf = vec![0; op.encoded_len()];
1287 op.encode(&mut buf[..]).expect("should succeed");
1288
1289 let bytes = vec![0x05, 0x0A];
1290 assert_eq!(buf, bytes);
1291
1292 let (decoded, len) = RemoveSourceOperation::decode(&bytes);
1294 assert_eq!(decoded, Ok(op));
1295 assert_eq!(len, 2);
1296 }
1297
1298 #[test]
1299 fn broadcast_receive_state_without_subgroups() {
1300 let state = BroadcastReceiveState::NonEmpty(ReceiveState {
1302 source_id: 0x01,
1303 source_address_type: AddressType::Public,
1304 source_address: [0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A],
1305 source_adv_sid: AdvertisingSetId(0x01),
1306 broadcast_id: BroadcastId::try_from(0x00010203).unwrap(),
1307 pa_sync_state: PaSyncState::Synced,
1308 big_encryption: EncryptionStatus::BadCode([
1309 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x7, 0x06, 0x05, 0x04, 0x03,
1310 0x02, 0x01,
1311 ]),
1312 subgroups: vec![],
1313 });
1314 assert_eq!(state.encoded_len(), 31);
1315 let mut buf = vec![0; state.encoded_len()];
1316 state.encode(&mut buf[..]).expect("should succeed");
1317
1318 let bytes = vec![
1319 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x01, 0x03, 0x02, 0x01, 0x02, 0x03,
1320 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
1321 0x02, 0x01, 0x00,
1323 ];
1324 assert_eq!(buf, bytes);
1325
1326 let (decoded, len) = BroadcastReceiveState::decode(&bytes);
1328 assert_eq!(decoded, Ok(state));
1329 assert_eq!(len, 31);
1330 }
1331
1332 #[test]
1333 fn broadcast_receive_state_with_subgroups() {
1334 let state = BroadcastReceiveState::NonEmpty(ReceiveState {
1336 source_id: 0x01,
1337 source_address_type: AddressType::Random,
1338 source_address: [0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A],
1339 source_adv_sid: AdvertisingSetId(0x01),
1340 broadcast_id: BroadcastId::try_from(0x00010203).unwrap(),
1341 pa_sync_state: PaSyncState::NotSynced,
1342 big_encryption: EncryptionStatus::NotEncrypted,
1343 subgroups: vec![
1344 BigSubgroup::new(None)
1345 .with_metadata(vec![Metadata::ParentalRating(Rating::AllAge)]), ],
1347 });
1348 assert_eq!(state.encoded_len(), 23);
1349 let mut buf = vec![0; state.encoded_len()];
1350 state.encode(&mut buf[..]).expect("should succeed");
1351
1352 let bytes = vec![
1353 0x01, 0x01, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x01, 0x03, 0x02, 0x01, 0x00, 0x00,
1354 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x02, 0x06, 0x01, ];
1357 assert_eq!(buf, bytes);
1358
1359 let (decoded, len) = BroadcastReceiveState::decode(&bytes);
1361 assert_eq!(decoded, Ok(state));
1362 assert_eq!(len, 23);
1363 }
1364}