bt_pacs/
debug.rs

1// Copyright 2023 Google LLC
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use bt_common::debug_command::CommandRunner;
6use bt_common::debug_command::CommandSet;
7use bt_common::gen_commandset;
8
9use bt_gatt::{
10    client::{PeerService, PeerServiceHandle},
11    Client,
12};
13
14use crate::*;
15
16gen_commandset! {
17    PacsCmd {
18        Print = ("print", [], [], "Print the current PACS status"),
19    }
20}
21
22pub struct PacsDebug<T: bt_gatt::GattTypes> {
23    client: T::Client,
24}
25
26impl<T: bt_gatt::GattTypes> PacsDebug<T> {
27    pub fn new(client: T::Client) -> Self {
28        Self { client }
29    }
30}
31
32impl<T: bt_gatt::GattTypes> CommandRunner for PacsDebug<T> {
33    type Set = PacsCmd;
34
35    fn run(
36        &self,
37        _cmd: Self::Set,
38        _args: Vec<String>,
39    ) -> impl futures::Future<Output = Result<(), impl std::error::Error>> {
40        async {
41            // Since there is only one command, Print, we just print
42            // all the characteristics that are at the remote PACS server.
43            let handles = self.client.find_service(PACS_UUID).await?;
44            for handle in handles {
45                let service = handle.connect().await?;
46
47                let chrs = service.discover_characteristics(None).await?;
48                for chr in chrs {
49                    let mut buf = [0; 120];
50                    match chr.uuid {
51                        SourcePac::UUID => {
52                            let source_pac = SourcePac::try_read::<T>(chr, &service).await?;
53                            println!("{source_pac:?}");
54                        }
55                        SinkPac::UUID => {
56                            let sink_pac = SinkPac::try_read::<T>(chr, &service).await?;
57                            println!("{sink_pac:?}");
58                        }
59                        SinkAudioLocations::UUID => {
60                            let locations =
61                                SinkAudioLocations::try_read::<T>(chr, &service).await?;
62                            println!("{locations:?}");
63                        }
64                        SourceAudioLocations::UUID => {
65                            let (bytes, _trunc) =
66                                service.read_characteristic(&chr.handle, 0, &mut buf).await?;
67                            let locations = SourceAudioLocations::from_chr(chr, &buf[..bytes])
68                                .map_err(bt_gatt::types::Error::other)?;
69                            println!("{locations:?}");
70                        }
71                        AvailableAudioContexts::UUID => {
72                            let (bytes, _trunc) =
73                                service.read_characteristic(&chr.handle, 0, &mut buf).await?;
74                            let contexts = AvailableAudioContexts::from_chr(chr, &buf[..bytes])
75                                .map_err(bt_gatt::types::Error::other)?;
76                            println!("{contexts:?}");
77                        }
78                        SupportedAudioContexts::UUID => {
79                            let (bytes, _trunc) =
80                                service.read_characteristic(&chr.handle, 0, &mut buf).await?;
81                            let contexts = SupportedAudioContexts::from_chr(chr, &buf[..bytes])
82                                .map_err(bt_gatt::types::Error::other)?;
83                            println!("{contexts:?}");
84                        }
85                        _x => println!("Unrecognized Chr {}", chr.uuid.recognize()),
86                    }
87                }
88            }
89            Ok::<(), bt_gatt::types::Error>(())
90        }
91    }
92}