Skip to main content

bluetooth_rust/
bluetooth_uuid.rs

1//! UUID stuff for android bluetooth
2
3#[cfg(target_os = "android")]
4use super::android::Java;
5#[cfg(target_os = "android")]
6use super::android::jerr;
7#[cfg(target_os = "android")]
8use jni_min_helper::*;
9#[cfg(target_os = "android")]
10use std::sync::{Arc, Mutex};
11
12/// Represents the uuid for a bluetooth service
13#[derive(Debug, PartialEq)]
14pub enum BluetoothUuid {
15    /// Android auto
16    AndroidAuto,
17    /// Serial port protocol
18    SPP,
19    /// a2dp source
20    A2dpSource,
21    /// a2dp sink
22    A2dpSink,
23    /// base bluetooth profile
24    Base,
25    /// headset protocol, hs
26    HspHs,
27    /// headset protocol ag
28    HspAg,
29    /// handsfree protocol, ag
30    HfpAg,
31    /// Handsfree protocol, hs
32    HfpHs,
33    /// Obex opp protocol
34    ObexOpp,
35    /// Obex ftp protocol
36    ObexFtp,
37    /// Obex mas protocol
38    ObexMas,
39    /// Obex mns protocol
40    ObexMns,
41    /// Obex pse protocol
42    ObexPse,
43    /// Obex sync protocol
44    ObexSync,
45    /// Avrcp remote protocol
46    AvrcpRemote,
47    /// Network nap protocol for bluetooth networking
48    NetworkingNap,
49    /// An unknown bluetooth uuid
50    Unknown(String),
51}
52
53impl BluetoothUuid {
54    /// Get the 16-bit id
55    pub fn get_16_bit_id(&self) -> u16 {
56        match self {
57            BluetoothUuid::SPP => 0x1101,
58            BluetoothUuid::A2dpSource => 0x110a,
59            BluetoothUuid::HfpHs => 0x111e,
60            BluetoothUuid::ObexOpp => 0x1105,
61            BluetoothUuid::ObexFtp => 0x1106,
62            BluetoothUuid::ObexSync => 0x1104,
63            BluetoothUuid::A2dpSink => 0x110b,
64            BluetoothUuid::AvrcpRemote => 0x110e,
65            BluetoothUuid::ObexPse => 0x112f,
66            BluetoothUuid::HfpAg => 0x111f,
67            BluetoothUuid::ObexMas => 0x1132,
68            BluetoothUuid::ObexMns => 0x1133,
69            BluetoothUuid::Base => 0,
70            BluetoothUuid::NetworkingNap => 0x1116,
71            BluetoothUuid::HspHs => 0x1108,
72            BluetoothUuid::HspAg => 0x1112,
73            BluetoothUuid::AndroidAuto => 0x7a00,
74            BluetoothUuid::Unknown(s) => u16::from_str_radix(&s[4..8], 16).unwrap(),
75        }
76    }
77
78    /// Get the uuid as a str reference
79    pub fn as_str(&self) -> &str {
80        match self {
81            BluetoothUuid::SPP => "00001101-0000-1000-8000-00805F9B34FB",
82            BluetoothUuid::A2dpSource => "0000110a-0000-1000-8000-00805f9b34fb",
83            BluetoothUuid::HfpHs => "0000111e-0000-1000-8000-00805f9b34fb",
84            BluetoothUuid::ObexOpp => "00001105-0000-1000-8000-00805f9b34fb",
85            BluetoothUuid::ObexFtp => "00001106-0000-1000-8000-00805f9b34fb",
86            BluetoothUuid::ObexSync => "00001104-0000-1000-8000-00805f9b34fb",
87            BluetoothUuid::A2dpSink => "0000110b-0000-1000-8000-00805f9b34fb",
88            BluetoothUuid::AvrcpRemote => "0000110e-0000-1000-8000-00805f9b34fb",
89            BluetoothUuid::ObexPse => "0000112f-0000-1000-8000-00805f9b34fb",
90            BluetoothUuid::HfpAg => "0000111f-0000-1000-8000-00805f9b34fb",
91            BluetoothUuid::ObexMas => "00001132-0000-1000-8000-00805f9b34fb",
92            BluetoothUuid::ObexMns => "00001133-0000-1000-8000-00805f9b34fb",
93            BluetoothUuid::Base => "00000000-0000-1000-8000-00805f9b34fb",
94            BluetoothUuid::NetworkingNap => "00001116-0000-1000-8000-00805f9b34fb",
95            BluetoothUuid::HspHs => "00001108-0000-1000-8000-00805f9b34fb",
96            BluetoothUuid::HspAg => "00001112-0000-1000-8000-00805f9b34fb",
97            BluetoothUuid::AndroidAuto => "4de17a00-52cb-11e6-bdf4-0800200c9a66",
98            BluetoothUuid::Unknown(s) => s,
99        }
100    }
101}
102
103impl std::str::FromStr for BluetoothUuid {
104    type Err = ();
105    fn from_str(s: &str) -> Result<Self, Self::Err> {
106        Ok(match s {
107            "00001101-0000-1000-8000-00805F9B34FB" => BluetoothUuid::SPP,
108            "0000110a-0000-1000-8000-00805f9b34fb" => BluetoothUuid::A2dpSource,
109            "0000111e-0000-1000-8000-00805f9b34fb" => BluetoothUuid::HfpHs,
110            "00001105-0000-1000-8000-00805f9b34fb" => BluetoothUuid::ObexOpp,
111            "00001106-0000-1000-8000-00805f9b34fb" => BluetoothUuid::ObexFtp,
112            "00001104-0000-1000-8000-00805f9b34fb" => BluetoothUuid::ObexSync,
113            "0000110b-0000-1000-8000-00805f9b34fb" => BluetoothUuid::A2dpSink,
114            "0000110e-0000-1000-8000-00805f9b34fb" => BluetoothUuid::AvrcpRemote,
115            "0000112f-0000-1000-8000-00805f9b34fb" => BluetoothUuid::ObexPse,
116            "0000111f-0000-1000-8000-00805f9b34fb" => BluetoothUuid::HfpAg,
117            "00001132-0000-1000-8000-00805f9b34fb" => BluetoothUuid::ObexMas,
118            "00001133-0000-1000-8000-00805f9b34fb" => BluetoothUuid::ObexMns,
119            "00000000-0000-1000-8000-00805f9b34fb" => BluetoothUuid::Base,
120            "00001116-0000-1000-8000-00805f9b34fb" => BluetoothUuid::NetworkingNap,
121            "00001108-0000-1000-8000-00805f9b34fb" => BluetoothUuid::HspHs,
122            "00001112-0000-1000-8000-00805f9b34fb" => BluetoothUuid::HspAg,
123            "4de17a00-52cb-11e6-bdf4-0800200c9a66" => BluetoothUuid::AndroidAuto,
124            _ => BluetoothUuid::Unknown(s.to_string()),
125        })
126    }
127}
128
129#[cfg(target_os = "android")]
130impl From<ParcelUuid> for BluetoothUuid {
131    fn from(value: ParcelUuid) -> Self {
132        use std::str::FromStr;
133        BluetoothUuid::from_str(&value.to_string().unwrap()).unwrap()
134    }
135}
136
137#[cfg(target_os = "android")]
138pub struct ParcelUuid {
139    internal: jni::objects::GlobalRef,
140    java: Arc<Mutex<Java>>,
141}
142
143#[cfg(target_os = "android")]
144impl std::fmt::Display for ParcelUuid {
145    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146        match self.to_string() {
147            Ok(s) => f.write_str(&s),
148            Err(e) => f.write_str(&format!("ERR: {}", e)),
149        }
150    }
151}
152
153#[cfg(target_os = "android")]
154impl ParcelUuid {
155    pub fn new(uuid: jni::objects::GlobalRef, java: Arc<Mutex<Java>>) -> Self {
156        Self {
157            internal: uuid,
158            java,
159        }
160    }
161
162    pub fn to_string(&self) -> Result<String, std::io::Error> {
163        let mut java = self.java.lock().unwrap();
164        java.use_env(|env, _context| {
165            let dev_name = env
166                .call_method(&self.internal, "toString", "()Ljava/lang/String;", &[])
167                .get_object(env)
168                .map_err(|e| jerr(env, e))?;
169            if dev_name.is_null() {
170                return Err(std::io::Error::from(std::io::ErrorKind::PermissionDenied));
171            }
172            dev_name.get_string(env).map_err(|e| jerr(env, e))
173        })
174    }
175}