1use dbus::{
4 arg::{OwnedFd, PropMap, Variant},
5 channel::Sender,
6 message::SignalArgs,
7 nonblock::{stdintf::org_freedesktop_dbus::PropertiesPropertiesChanged, Proxy, SyncConnection},
8 MethodErr, Path,
9};
10use dbus_crossroads::{Crossroads, IfaceBuilder, IfaceToken};
11use futures::{channel::oneshot, lock::Mutex, Future, FutureExt, Stream};
12use pin_project::pin_project;
13use std::{
14 collections::HashSet,
15 fmt,
16 mem::take,
17 num::NonZeroU16,
18 pin::Pin,
19 sync::{Arc, Weak},
20 task::Poll,
21};
22use strum::{Display, EnumString, IntoStaticStr};
23use tokio::sync::{mpsc, watch};
24use tokio_stream::wrappers::ReceiverStream;
25use uuid::Uuid;
26
27use super::{
28 make_socket_pair, mtu_workaround, CharacteristicFlags, CharacteristicReader, CharacteristicWriter,
29 DescriptorFlags, WriteOp, CHARACTERISTIC_INTERFACE, DESCRIPTOR_INTERFACE, SERVICE_INTERFACE,
30};
31use crate::{
32 method_call, parent_path, Adapter, Address, DbusResult, Device, Error, ErrorKind, Result, SessionInner,
33 ERR_PREFIX, SERVICE_NAME, TIMEOUT,
34};
35
36pub(crate) const MANAGER_INTERFACE: &str = "org.bluez.GattManager1";
37
38#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Display, EnumString)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41pub enum LinkType {
42 #[strum(serialize = "BR/EDR")]
44 BrEdr,
45 #[strum(serialize = "LE")]
47 Le,
48}
49
50#[derive(Clone, Copy, Debug, displaydoc::Display, Eq, PartialEq, Ord, PartialOrd, Hash, IntoStaticStr)]
56#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
57#[non_exhaustive]
58pub enum ReqError {
59 Failed,
61 InProgress,
63 InvalidOffset,
65 InvalidValueLength,
67 NotPermitted,
69 NotAuthorized,
71 NotSupported,
73}
74
75impl std::error::Error for ReqError {}
76
77impl Default for ReqError {
78 fn default() -> Self {
79 Self::Failed
80 }
81}
82
83impl From<ReqError> for dbus::MethodErr {
84 fn from(err: ReqError) -> Self {
85 let name: &'static str = err.into();
86 Self::from((ERR_PREFIX.to_string() + name, &err.to_string()))
87 }
88}
89
90pub type ReqResult<T> = std::result::Result<T, ReqError>;
92
93#[derive(Debug, Default)]
103pub struct Service {
104 pub uuid: Uuid,
106 pub handle: Option<NonZeroU16>,
110 pub primary: bool,
115 pub characteristics: Vec<Characteristic>,
117 pub control_handle: ServiceControlHandle,
119 #[doc(hidden)]
120 pub _non_exhaustive: (),
121}
122
123pub struct ServiceControl {
131 handle_rx: watch::Receiver<Option<NonZeroU16>>,
132}
133
134impl fmt::Debug for ServiceControl {
135 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
136 write!(f, "ServiceControl {{ handle: {} }}", self.handle().map(|h| h.get()).unwrap_or_default())
137 }
138}
139
140impl ServiceControl {
141 pub fn handle(&self) -> crate::Result<NonZeroU16> {
143 match *self.handle_rx.borrow() {
144 Some(handle) => Ok(handle),
145 None => Err(Error::new(ErrorKind::NotRegistered)),
146 }
147 }
148}
149
150pub struct ServiceControlHandle {
155 handle_tx: watch::Sender<Option<NonZeroU16>>,
156}
157
158impl Default for ServiceControlHandle {
159 fn default() -> Self {
160 Self { handle_tx: watch::channel(None).0 }
161 }
162}
163
164impl fmt::Debug for ServiceControlHandle {
165 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
166 write!(f, "ServiceControlHandle")
167 }
168}
169
170pub fn service_control() -> (ServiceControl, ServiceControlHandle) {
174 let (handle_tx, handle_rx) = watch::channel(None);
175 (ServiceControl { handle_rx }, ServiceControlHandle { handle_tx })
176}
177
178pub(crate) struct RegisteredService {
184 s: Service,
185}
186
187impl RegisteredService {
188 fn new(s: Service) -> Self {
189 if let Some(handle) = s.handle {
190 let _ = s.control_handle.handle_tx.send(Some(handle));
191 }
192 Self { s }
193 }
194
195 pub(crate) fn register_interface(cr: &mut Crossroads) -> IfaceToken<Arc<Self>> {
196 cr.register(SERVICE_INTERFACE, |ib: &mut IfaceBuilder<Arc<Self>>| {
197 cr_property!(ib, "UUID", reg => {
198 Some(reg.s.uuid.to_string())
199 });
200 cr_property!(ib, "Primary", reg => {
201 Some(reg.s.primary)
202 });
203 ib.property("Handle").get(|_ctx, reg| Ok(reg.s.handle.map(|h| h.get()).unwrap_or_default())).set(
204 |ctx, reg, handle| {
205 log::trace!("{}: {}.Handle <- {}", ctx.path(), SERVICE_INTERFACE, handle);
206 let handle = NonZeroU16::new(handle);
207 let _ = reg.s.control_handle.handle_tx.send(handle);
208 Ok(None)
209 },
210 );
211 })
212 }
213}
214
215pub type CharacteristicReadFun = Box<
225 dyn (Fn(CharacteristicReadRequest) -> Pin<Box<dyn Future<Output = ReqResult<Vec<u8>>> + Send>>) + Send + Sync,
226>;
227
228#[derive(custom_debug::Debug)]
230pub struct CharacteristicRead {
231 pub read: bool,
233 pub encrypt_read: bool,
235 pub encrypt_authenticated_read: bool,
237 pub secure_read: bool,
239 #[debug(skip)]
241 pub fun: CharacteristicReadFun,
242 #[doc(hidden)]
243 pub _non_exhaustive: (),
244}
245
246impl Default for CharacteristicRead {
247 fn default() -> Self {
248 Self {
249 read: false,
250 encrypt_read: false,
251 encrypt_authenticated_read: false,
252 secure_read: false,
253 fun: Box::new(|_| async move { Err(ReqError::NotSupported) }.boxed()),
254 _non_exhaustive: (),
255 }
256 }
257}
258
259impl CharacteristicRead {
260 fn set_characteristic_flags(&self, f: &mut CharacteristicFlags) {
261 f.read = self.read;
262 f.encrypt_read = self.encrypt_read;
263 f.encrypt_authenticated_read = self.encrypt_authenticated_read;
264 f.secure_read = self.secure_read;
265 }
266}
267
268pub type CharacteristicWriteFun = Box<
270 dyn Fn(Vec<u8>, CharacteristicWriteRequest) -> Pin<Box<dyn Future<Output = ReqResult<()>> + Send>>
271 + Send
272 + Sync,
273>;
274
275pub enum CharacteristicWriteMethod {
277 Fun(CharacteristicWriteFun),
279 Io,
284}
285
286impl fmt::Debug for CharacteristicWriteMethod {
287 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
288 match self {
289 Self::Fun(_) => write!(f, "Fun"),
290 Self::Io => write!(f, "Io"),
291 }
292 }
293}
294
295impl Default for CharacteristicWriteMethod {
296 fn default() -> Self {
297 Self::Fun(Box::new(|_, _| async move { Err(ReqError::NotSupported) }.boxed()))
298 }
299}
300
301#[derive(Debug, Default)]
303pub struct CharacteristicWrite {
304 pub write: bool,
306 pub write_without_response: bool,
308 pub reliable_write: bool,
310 pub authenticated_signed_writes: bool,
312 pub encrypt_write: bool,
314 pub encrypt_authenticated_write: bool,
316 pub secure_write: bool,
318 pub method: CharacteristicWriteMethod,
320 #[doc(hidden)]
321 pub _non_exhaustive: (),
322}
323
324impl CharacteristicWrite {
325 fn set_characteristic_flags(&self, f: &mut CharacteristicFlags) {
326 f.write = self.write;
327 f.write_without_response = self.write_without_response;
328 f.reliable_write = self.reliable_write;
329 f.authenticated_signed_writes = self.authenticated_signed_writes;
330 f.encrypt_write = self.encrypt_write;
331 f.encrypt_authenticated_write = self.encrypt_authenticated_write;
332 f.secure_write = self.secure_write;
333 }
334}
335
336pub type CharacteristicNotifyFun =
341 Box<dyn Fn(CharacteristicNotifier) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>;
342
343pub enum CharacteristicNotifyMethod {
345 Fun(CharacteristicNotifyFun),
347 Io,
352}
353
354impl Default for CharacteristicNotifyMethod {
355 fn default() -> Self {
356 Self::Fun(Box::new(|_| async move {}.boxed()))
357 }
358}
359
360impl fmt::Debug for CharacteristicNotifyMethod {
361 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
362 match self {
363 Self::Fun(_) => write!(f, "Fun"),
364 Self::Io => write!(f, "Io"),
365 }
366 }
367}
368
369#[derive(Debug, Default)]
371pub struct CharacteristicNotify {
372 pub notify: bool,
374 pub indicate: bool,
378 pub method: CharacteristicNotifyMethod,
380 #[doc(hidden)]
381 pub _non_exhaustive: (),
382}
383
384impl CharacteristicNotify {
385 fn set_characteristic_flags(&self, f: &mut CharacteristicFlags) {
386 f.notify = self.notify;
387 f.indicate = self.indicate;
388 }
389}
390
391#[derive(Default, Debug)]
393pub struct Characteristic {
394 pub uuid: Uuid,
396 pub handle: Option<NonZeroU16>,
400 pub broadcast: bool,
403 pub writable_auxiliaries: bool,
405 pub authorize: bool,
407 pub descriptors: Vec<Descriptor>,
409 pub read: Option<CharacteristicRead>,
411 pub write: Option<CharacteristicWrite>,
413 pub notify: Option<CharacteristicNotify>,
415 pub control_handle: CharacteristicControlHandle,
417 #[doc(hidden)]
418 pub _non_exhaustive: (),
419}
420
421impl Characteristic {
422 fn set_characteristic_flags(&self, f: &mut CharacteristicFlags) {
423 f.broadcast = self.broadcast;
424 f.writable_auxiliaries = self.writable_auxiliaries;
425 f.authorize = self.authorize;
426 }
427}
428
429fn parse_device(dict: &PropMap) -> DbusResult<(String, Address)> {
435 let path = read_prop!(dict, "device", Path);
436 let (adapter, addr) = Device::parse_dbus_path(&path).ok_or_else(|| {
437 log::warn!("cannot parse device path: {}", path);
438 MethodErr::invalid_arg("device")
439 })?;
440 Ok((adapter.to_string(), addr))
441}
442
443#[derive(Debug, Clone)]
445#[non_exhaustive]
446pub struct CharacteristicReadRequest {
447 pub adapter_name: String,
449 pub device_address: Address,
451 pub offset: u16,
453 pub mtu: u16,
455 pub link: Option<LinkType>,
457}
458
459impl CharacteristicReadRequest {
460 fn from_dict(dict: &PropMap) -> DbusResult<Self> {
461 let (adapter_name, device_address) = parse_device(dict)?;
462 Ok(Self {
463 adapter_name,
464 device_address,
465 offset: read_opt_prop!(dict, "offset", u16).unwrap_or_default(),
466 mtu: read_prop!(dict, "mtu", u16),
467 link: read_opt_prop!(dict, "link", String).and_then(|v| v.parse().ok()),
468 })
469 }
470}
471
472#[derive(Debug, Clone)]
474#[non_exhaustive]
475pub struct CharacteristicWriteRequest {
476 pub adapter_name: String,
478 pub device_address: Address,
480 pub offset: u16,
482 pub op_type: WriteOp,
484 pub mtu: u16,
486 pub link: Option<LinkType>,
488 pub prepare_authorize: bool,
490}
491
492impl CharacteristicWriteRequest {
493 fn from_dict(dict: &PropMap) -> DbusResult<Self> {
494 let (adapter_name, device_address) = parse_device(dict)?;
495 Ok(Self {
496 adapter_name,
497 device_address,
498 offset: read_opt_prop!(dict, "offset", u16).unwrap_or_default(),
499 op_type: read_opt_prop!(dict, "type", String)
500 .map(|s| s.parse().map_err(|_| MethodErr::invalid_arg("type")))
501 .transpose()?
502 .unwrap_or_default(),
503 mtu: read_prop!(dict, "mtu", u16),
504 link: read_opt_prop!(dict, "link", String).and_then(|v| v.parse().ok()),
505 prepare_authorize: read_opt_prop!(dict, "prepare-authorize", bool).unwrap_or_default(),
506 })
507 }
508}
509
510pub struct CharacteristicNotifier {
514 connection: Weak<SyncConnection>,
515 path: Path<'static>,
516 stop_notify_tx: mpsc::Sender<()>,
517 confirm_rx: Option<mpsc::Receiver<()>>,
518}
519
520impl CharacteristicNotifier {
521 pub fn confirming(&self) -> bool {
525 self.confirm_rx.is_some()
526 }
527
528 pub fn is_stopped(&self) -> bool {
530 self.stop_notify_tx.is_closed()
531 }
532
533 pub fn stopped(&self) -> impl Future<Output = ()> {
535 let stop_notify_tx = self.stop_notify_tx.clone();
536 async move { stop_notify_tx.closed().await }
537 }
538
539 pub async fn notify(&mut self, value: Vec<u8>) -> Result<()> {
546 let connection =
547 self.connection.upgrade().ok_or_else(|| Error::new(ErrorKind::NotificationSessionStopped))?;
548 if self.is_stopped() {
549 return Err(Error::new(ErrorKind::NotificationSessionStopped));
550 }
551
552 if let Some(confirm_rx) = &mut self.confirm_rx {
556 while let Some(Some(())) = confirm_rx.recv().now_or_never() {}
557 }
558
559 let mut changed_properties = PropMap::new();
561 changed_properties.insert("Value".to_string(), Variant(Box::new(value)));
562 let ppc = PropertiesPropertiesChanged {
563 interface_name: CHARACTERISTIC_INTERFACE.to_string(),
564 changed_properties,
565 invalidated_properties: Vec::new(),
566 };
567 let msg = ppc.to_emit_message(&self.path);
568 connection.send(msg).map_err(|_| Error::new(ErrorKind::NotificationSessionStopped))?;
569 drop(connection);
570
571 if let Some(confirm_rx) = &mut self.confirm_rx {
574 match confirm_rx.recv().await {
575 Some(()) => Ok(()),
576 None => Err(Error::new(ErrorKind::IndicationUnconfirmed)),
577 }
578 } else {
579 Ok(())
580 }
581 }
582}
583
584pub struct CharacteristicWriteIoRequest {
590 adapter_name: String,
591 device_address: Address,
592 mtu: u16,
593 link: Option<LinkType>,
594 tx: oneshot::Sender<ReqResult<OwnedFd>>,
595}
596
597impl CharacteristicWriteIoRequest {
598 pub fn adapter_name(&self) -> &str {
600 &self.adapter_name
601 }
602
603 pub fn device_address(&self) -> Address {
605 self.device_address
606 }
607
608 pub fn mtu(&self) -> usize {
610 self.mtu.into()
611 }
612
613 pub fn link(&self) -> Option<LinkType> {
615 self.link
616 }
617
618 pub fn accept(self) -> Result<CharacteristicReader> {
620 let CharacteristicWriteIoRequest { adapter_name, device_address, mtu, tx, .. } = self;
621 let (fd, socket) = make_socket_pair(false)?;
622 let _ = tx.send(Ok(fd));
623 Ok(CharacteristicReader { adapter_name, device_address, mtu: mtu.into(), socket, buf: Vec::new() })
624 }
625
626 pub fn reject(self, reason: ReqError) {
628 let _ = self.tx.send(Err(reason));
629 }
630}
631
632pub enum CharacteristicControlEvent {
638 Write(CharacteristicWriteIoRequest),
642 Notify(CharacteristicWriter),
649}
650
651impl fmt::Debug for CharacteristicControlEvent {
652 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
653 match self {
654 Self::Write(_) => write!(f, "Write"),
655 Self::Notify(_) => write!(f, "Notify"),
656 }
657 }
658}
659
660#[pin_project]
664pub struct CharacteristicControl {
665 handle_rx: watch::Receiver<Option<NonZeroU16>>,
666 #[pin]
667 events_rx: ReceiverStream<CharacteristicControlEvent>,
668}
669
670impl fmt::Debug for CharacteristicControl {
671 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
672 write!(f, "CharacteristicControl {{ handle: {} }}", self.handle().map(|h| h.get()).unwrap_or_default())
673 }
674}
675
676impl CharacteristicControl {
677 pub fn handle(&self) -> crate::Result<NonZeroU16> {
679 match *self.handle_rx.borrow() {
680 Some(handle) => Ok(handle),
681 None => Err(Error::new(ErrorKind::NotRegistered)),
682 }
683 }
684}
685
686impl Stream for CharacteristicControl {
687 type Item = CharacteristicControlEvent;
688
689 fn poll_next(self: Pin<&mut Self>, cx: &mut std::task::Context) -> Poll<Option<Self::Item>> {
690 self.project().events_rx.poll_next(cx)
691 }
692}
693
694pub struct CharacteristicControlHandle {
699 handle_tx: watch::Sender<Option<NonZeroU16>>,
700 events_tx: mpsc::Sender<CharacteristicControlEvent>,
701}
702
703impl Default for CharacteristicControlHandle {
704 fn default() -> Self {
705 Self { handle_tx: watch::channel(None).0, events_tx: mpsc::channel(1).0 }
706 }
707}
708
709impl fmt::Debug for CharacteristicControlHandle {
710 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
711 write!(f, "CharacteristicControlHandle")
712 }
713}
714
715pub fn characteristic_control() -> (CharacteristicControl, CharacteristicControlHandle) {
719 let (handle_tx, handle_rx) = watch::channel(None);
720 let (events_tx, events_rx) = mpsc::channel(1);
721 (
722 CharacteristicControl { handle_rx, events_rx: ReceiverStream::new(events_rx) },
723 CharacteristicControlHandle { handle_tx, events_tx },
724 )
725}
726
727#[derive(Debug, Clone)]
733#[non_exhaustive]
734struct CharacteristicAcquireRequest {
735 pub adapter_name: String,
737 pub device_address: Address,
739 pub mtu: u16,
741 pub link: Option<LinkType>,
743}
744
745impl CharacteristicAcquireRequest {
746 fn from_dict(dict: &PropMap) -> DbusResult<Self> {
747 let (adapter, device) = parse_device(dict)?;
748 Ok(Self {
749 adapter_name: adapter,
750 device_address: device,
751 mtu: read_prop!(dict, "mtu", u16),
752 link: read_opt_prop!(dict, "link", String).and_then(|v| v.parse().ok()),
753 })
754 }
755}
756
757struct CharacteristicNotifyState {
759 confirm_tx: Option<mpsc::Sender<()>>,
760 _stop_notify_rx: mpsc::Receiver<()>,
761}
762
763pub(crate) struct RegisteredCharacteristic {
765 c: Characteristic,
766 notify: Mutex<Option<CharacteristicNotifyState>>,
767 connection: Weak<SyncConnection>,
768}
769
770impl RegisteredCharacteristic {
771 fn new(c: Characteristic, connection: &Arc<SyncConnection>) -> Self {
772 if let Some(handle) = c.handle {
773 let _ = c.control_handle.handle_tx.send(Some(handle));
774 }
775 Self { c, notify: Mutex::new(None), connection: Arc::downgrade(connection) }
776 }
777
778 pub(crate) fn register_interface(cr: &mut Crossroads) -> IfaceToken<Arc<Self>> {
779 cr.register(CHARACTERISTIC_INTERFACE, |ib: &mut IfaceBuilder<Arc<Self>>| {
780 cr_property!(ib, "UUID", reg => {
781 Some(reg.c.uuid.to_string())
782 });
783 cr_property!(ib, "Flags", reg => {
784 let mut flags = CharacteristicFlags::default();
785 reg.c.set_characteristic_flags(&mut flags);
786 if let Some(read) = ®.c.read {
787 read.set_characteristic_flags(&mut flags);
788 }
789 if let Some(write) = ®.c.write {
790 write.set_characteristic_flags(&mut flags);
791 }
792 if let Some(notify) = ®.c.notify {
793 notify.set_characteristic_flags(&mut flags);
794 }
795 Some(flags.as_vec())
796 });
797 ib.property("Service").get(|ctx, _| Ok(parent_path(ctx.path())));
798 ib.property("Handle").get(|_ctx, reg| Ok(reg.c.handle.map(|h| h.get()).unwrap_or_default())).set(
799 |ctx, reg, handle| {
800 log::trace!("{}: {}.Handle <- {}", ctx.path(), CHARACTERISTIC_INTERFACE, handle);
801 let handle = NonZeroU16::new(handle);
802 let _ = reg.c.control_handle.handle_tx.send(handle);
803 Ok(None)
804 },
805 );
806 cr_property!(ib, "WriteAcquired", reg => {
807 match ®.c.write {
808 Some(CharacteristicWrite { method: CharacteristicWriteMethod::Io, .. }) =>
809 Some(false),
810 _ => None,
811 }
812 });
813 cr_property!(ib, "NotifyAcquired", reg => {
814 match ®.c.notify {
815 Some(CharacteristicNotify { method: CharacteristicNotifyMethod::Io, .. }) =>
816 Some(false),
817 _ => None,
818 }
819 });
820 ib.method_with_cr_async("ReadValue", ("options",), ("value",), |ctx, cr, (options,): (PropMap,)| {
821 method_call(ctx, cr, |reg: Arc<Self>| async move {
822 let options = CharacteristicReadRequest::from_dict(&options)?;
823 match ®.c.read {
824 Some(read) => {
825 let value = (read.fun)(options).await?;
826 Ok((value,))
827 }
828 None => Err(ReqError::NotSupported.into()),
829 }
830 })
831 });
832 ib.method_with_cr_async(
833 "WriteValue",
834 ("value", "options"),
835 (),
836 |ctx, cr, (value, options): (Vec<u8>, PropMap)| {
837 method_call(ctx, cr, |reg: Arc<Self>| async move {
838 let options = CharacteristicWriteRequest::from_dict(&options)?;
839 match ®.c.write {
840 Some(CharacteristicWrite { method: CharacteristicWriteMethod::Fun(fun), .. }) => {
841 fun(value, options).await?;
842 Ok(())
843 }
844 _ => Err(ReqError::NotSupported.into()),
845 }
846 })
847 },
848 );
849 ib.method_with_cr_async("StartNotify", (), (), |ctx, cr, ()| {
850 let path = ctx.path().clone();
851 method_call(ctx, cr, |reg: Arc<Self>| async move {
852 match ®.c.notify {
853 Some(CharacteristicNotify {
854 method: CharacteristicNotifyMethod::Fun(notify_fn),
855 indicate,
856 notify,
857 _non_exhaustive: (),
858 }) => {
859 let (stop_notify_tx, stop_notify_rx) = mpsc::channel(1);
860 let (confirm_tx, confirm_rx) = if *indicate && !*notify {
861 let (tx, rx) = mpsc::channel(1);
862 (Some(tx), Some(rx))
863 } else {
864 (None, None)
865 };
866 {
867 let mut notify = reg.notify.lock().await;
868 *notify = Some(CharacteristicNotifyState {
869 _stop_notify_rx: stop_notify_rx,
870 confirm_tx,
871 });
872 }
873 let notifier = CharacteristicNotifier {
874 connection: reg.connection.clone(),
875 path,
876 stop_notify_tx,
877 confirm_rx,
878 };
879 notify_fn(notifier).await;
880 Ok(())
881 }
882 _ => Err(ReqError::NotSupported.into()),
883 }
884 })
885 });
886 ib.method_with_cr_async("StopNotify", (), (), |ctx, cr, ()| {
887 method_call(ctx, cr, |reg: Arc<Self>| async move {
888 let mut notify = reg.notify.lock().await;
889 *notify = None;
890 Ok(())
891 })
892 });
893 ib.method_with_cr_async("Confirm", (), (), |ctx, cr, ()| {
894 method_call(ctx, cr, |reg: Arc<Self>| async move {
895 let mut notify = reg.notify.lock().await;
896 if let Some(CharacteristicNotifyState { confirm_tx: Some(confirm_tx), .. }) = &mut *notify {
897 let _ = confirm_tx.send(()).await;
898 }
899 Ok(())
900 })
901 });
902 ib.method_with_cr_async(
903 "AcquireWrite",
904 ("options",),
905 ("fd", "mtu"),
906 |ctx, cr, (options,): (PropMap,)| {
907 method_call(ctx, cr, |reg: Arc<Self>| async move {
908 let options = CharacteristicAcquireRequest::from_dict(&options)?;
909 match ®.c.write {
910 Some(CharacteristicWrite { method: CharacteristicWriteMethod::Io, .. }) => {
911 let (tx, rx) = oneshot::channel();
912 let req = CharacteristicWriteIoRequest {
913 adapter_name: options.adapter_name.clone(),
914 device_address: options.device_address,
915 mtu: options.mtu,
916 link: options.link,
917 tx,
918 };
919 reg.c
920 .control_handle
921 .events_tx
922 .send(CharacteristicControlEvent::Write(req))
923 .await
924 .map_err(|_| ReqError::Failed)?;
925 let fd = rx.await.map_err(|_| ReqError::Failed)??;
926 Ok((fd, options.mtu))
927 }
928 _ => Err(ReqError::NotSupported.into()),
929 }
930 })
931 },
932 );
933 ib.method_with_cr_async(
934 "AcquireNotify",
935 ("options",),
936 ("fd", "mtu"),
937 |ctx, cr, (options,): (PropMap,)| {
938 method_call(ctx, cr, |reg: Arc<Self>| async move {
939 let options = CharacteristicAcquireRequest::from_dict(&options)?;
940 match ®.c.notify {
941 Some(CharacteristicNotify { method: CharacteristicNotifyMethod::Io, .. }) => {
942 let (fd, socket) = make_socket_pair(true).map_err(|_| ReqError::Failed)?;
945 let mtu = mtu_workaround(options.mtu.into());
946 let writer = CharacteristicWriter {
947 adapter_name: options.adapter_name.clone(),
948 device_address: options.device_address,
949 mtu,
950 socket,
951 };
952 let _ = reg
953 .c
954 .control_handle
955 .events_tx
956 .send(CharacteristicControlEvent::Notify(writer))
957 .await;
958 Ok((fd, options.mtu))
959 }
960 _ => Err(ReqError::NotSupported.into()),
961 }
962 })
963 },
964 );
965 })
966 }
967}
968
969pub type DescriptorReadFun =
979 Box<dyn Fn(DescriptorReadRequest) -> Pin<Box<dyn Future<Output = ReqResult<Vec<u8>>> + Send>> + Send + Sync>;
980
981#[derive(custom_debug::Debug)]
983pub struct DescriptorRead {
984 pub read: bool,
986 pub encrypt_read: bool,
988 pub encrypt_authenticated_read: bool,
990 pub secure_read: bool,
992 #[debug(skip)]
994 pub fun: DescriptorReadFun,
995 #[doc(hidden)]
996 pub _non_exhaustive: (),
997}
998
999impl Default for DescriptorRead {
1000 fn default() -> Self {
1001 Self {
1002 read: false,
1003 encrypt_read: false,
1004 encrypt_authenticated_read: false,
1005 secure_read: false,
1006 fun: Box::new(|_| async move { Err(ReqError::NotSupported) }.boxed()),
1007 _non_exhaustive: (),
1008 }
1009 }
1010}
1011
1012impl DescriptorRead {
1013 fn set_descriptor_flags(&self, f: &mut DescriptorFlags) {
1014 f.read = self.read;
1015 f.encrypt_read = self.encrypt_read;
1016 f.encrypt_authenticated_read = self.encrypt_authenticated_read;
1017 f.secure_read = self.secure_read;
1018 }
1019}
1020
1021pub type DescriptorWriteFun = Box<
1023 dyn Fn(Vec<u8>, DescriptorWriteRequest) -> Pin<Box<dyn Future<Output = ReqResult<()>> + Send>> + Send + Sync,
1024>;
1025
1026#[derive(custom_debug::Debug)]
1028pub struct DescriptorWrite {
1029 pub write: bool,
1031 pub encrypt_write: bool,
1033 pub encrypt_authenticated_write: bool,
1035 pub secure_write: bool,
1037 #[debug(skip)]
1039 pub fun: DescriptorWriteFun,
1040 #[doc(hidden)]
1041 pub _non_exhaustive: (),
1042}
1043
1044impl Default for DescriptorWrite {
1045 fn default() -> Self {
1046 Self {
1047 write: false,
1048 encrypt_write: false,
1049 encrypt_authenticated_write: false,
1050 secure_write: false,
1051 fun: Box::new(|_, _| async move { Err(ReqError::NotSupported) }.boxed()),
1052 _non_exhaustive: (),
1053 }
1054 }
1055}
1056
1057impl DescriptorWrite {
1058 fn set_descriptor_flags(&self, f: &mut DescriptorFlags) {
1059 f.write = self.write;
1060 f.encrypt_write = self.encrypt_write;
1061 f.encrypt_authenticated_write = self.encrypt_authenticated_write;
1062 f.secure_write = self.secure_write;
1063 }
1064}
1065
1066#[derive(Default, Debug)]
1068pub struct Descriptor {
1069 pub uuid: Uuid,
1071 pub handle: Option<NonZeroU16>,
1075 pub authorize: bool,
1077 pub read: Option<DescriptorRead>,
1079 pub write: Option<DescriptorWrite>,
1081 pub control_handle: DescriptorControlHandle,
1083 #[doc(hidden)]
1084 pub _non_exhaustive: (),
1085}
1086
1087impl Descriptor {
1088 fn set_descriptor_flags(&self, f: &mut DescriptorFlags) {
1089 f.authorize = self.authorize;
1090 }
1091}
1092
1093#[derive(Debug, Clone)]
1099#[non_exhaustive]
1100pub struct DescriptorReadRequest {
1101 pub adapter_name: String,
1103 pub device_address: Address,
1105 pub offset: u16,
1107 pub link: Option<LinkType>,
1109}
1110
1111impl DescriptorReadRequest {
1112 fn from_dict(dict: &PropMap) -> DbusResult<Self> {
1113 let (adapter_name, device_address) = parse_device(dict)?;
1114 Ok(Self {
1115 adapter_name,
1116 device_address,
1117 offset: read_opt_prop!(dict, "offset", u16).unwrap_or_default(),
1118 link: read_opt_prop!(dict, "link", String).and_then(|v| v.parse().ok()),
1119 })
1120 }
1121}
1122
1123#[derive(Debug, Clone)]
1125#[non_exhaustive]
1126pub struct DescriptorWriteRequest {
1127 pub adapter_name: String,
1129 pub device_address: Address,
1131 pub offset: u16,
1133 pub link: Option<LinkType>,
1135 pub prepare_authorize: bool,
1137}
1138
1139impl DescriptorWriteRequest {
1140 fn from_dict(dict: &PropMap) -> DbusResult<Self> {
1141 let (adapter_name, device_address) = parse_device(dict)?;
1142 Ok(Self {
1143 adapter_name,
1144 device_address,
1145 offset: read_opt_prop!(dict, "offset", u16).unwrap_or_default(),
1146 link: read_opt_prop!(dict, "link", String).and_then(|v| v.parse().ok()),
1147 prepare_authorize: read_prop!(dict, "prepare_authorize", bool),
1148 })
1149 }
1150}
1151
1152pub struct DescriptorControl {
1160 handle_rx: watch::Receiver<Option<NonZeroU16>>,
1161}
1162
1163impl fmt::Debug for DescriptorControl {
1164 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1165 write!(f, "DescriptorControl {{ handle: {} }}", self.handle().map(|h| h.get()).unwrap_or_default())
1166 }
1167}
1168
1169impl DescriptorControl {
1170 pub fn handle(&self) -> crate::Result<NonZeroU16> {
1172 match *self.handle_rx.borrow() {
1173 Some(handle) => Ok(handle),
1174 None => Err(Error::new(ErrorKind::NotRegistered)),
1175 }
1176 }
1177}
1178
1179pub struct DescriptorControlHandle {
1184 handle_tx: watch::Sender<Option<NonZeroU16>>,
1185}
1186
1187impl Default for DescriptorControlHandle {
1188 fn default() -> Self {
1189 Self { handle_tx: watch::channel(None).0 }
1190 }
1191}
1192
1193impl fmt::Debug for DescriptorControlHandle {
1194 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1195 write!(f, "DescriptorControlHandle")
1196 }
1197}
1198
1199pub fn descriptor_control() -> (DescriptorControl, DescriptorControlHandle) {
1203 let (handle_tx, handle_rx) = watch::channel(None);
1204 (DescriptorControl { handle_rx }, DescriptorControlHandle { handle_tx })
1205}
1206
1207pub(crate) struct RegisteredDescriptor {
1213 d: Descriptor,
1214}
1215
1216impl RegisteredDescriptor {
1217 fn new(d: Descriptor) -> Self {
1218 if let Some(handle) = d.handle {
1219 let _ = d.control_handle.handle_tx.send(Some(handle));
1220 }
1221 Self { d }
1222 }
1223
1224 pub(crate) fn register_interface(cr: &mut Crossroads) -> IfaceToken<Arc<Self>> {
1225 cr.register(DESCRIPTOR_INTERFACE, |ib: &mut IfaceBuilder<Arc<Self>>| {
1226 cr_property!(ib, "UUID", reg => {
1227 Some(reg.d.uuid.to_string())
1228 });
1229 cr_property!(ib, "Flags", reg => {
1230 let mut flags = DescriptorFlags::default();
1231 reg.d.set_descriptor_flags(&mut flags);
1232 if let Some(read) = ®.d.read {
1233 read.set_descriptor_flags(&mut flags);
1234 }
1235 if let Some(write) = ®.d.write {
1236 write.set_descriptor_flags(&mut flags);
1237 }
1238 Some(flags.as_vec())
1239 });
1240 ib.property("Characteristic").get(|ctx, _| Ok(parent_path(ctx.path())));
1241 ib.property("Handle").get(|_ctx, reg| Ok(reg.d.handle.map(|h| h.get()).unwrap_or_default())).set(
1242 |ctx, reg, handle| {
1243 log::trace!("{}: {}.Handle <- {}", ctx.path(), DESCRIPTOR_INTERFACE, handle);
1244 let handle = NonZeroU16::new(handle);
1245 let _ = reg.d.control_handle.handle_tx.send(handle);
1246 Ok(None)
1247 },
1248 );
1249 ib.method_with_cr_async("ReadValue", ("flags",), ("value",), |ctx, cr, (flags,): (PropMap,)| {
1250 method_call(ctx, cr, |reg: Arc<Self>| async move {
1251 let options = DescriptorReadRequest::from_dict(&flags)?;
1252 match ®.d.read {
1253 Some(read) => {
1254 let value = (read.fun)(options).await?;
1255 Ok((value,))
1256 }
1257 None => Err(ReqError::NotSupported.into()),
1258 }
1259 })
1260 });
1261 ib.method_with_cr_async(
1262 "WriteValue",
1263 ("value", "flags"),
1264 (),
1265 |ctx, cr, (value, flags): (Vec<u8>, PropMap)| {
1266 method_call(ctx, cr, |reg: Arc<Self>| async move {
1267 let options = DescriptorWriteRequest::from_dict(&flags)?;
1268 match ®.d.write {
1269 Some(write) => {
1270 (write.fun)(value, options).await?;
1271 Ok(())
1272 }
1273 None => Err(ReqError::NotSupported.into()),
1274 }
1275 })
1276 },
1277 );
1278 })
1279 }
1280}
1281
1282pub(crate) const GATT_APP_PREFIX: &str = publish_path!("gatt/app/");
1287
1288#[derive(Debug, Default)]
1290pub struct Application {
1291 pub services: Vec<Service>,
1293 #[doc(hidden)]
1294 pub _non_exhaustive: (),
1295}
1296
1297impl Application {
1298 pub(crate) async fn register(
1299 mut self, inner: Arc<SessionInner>, adapter_name: Arc<String>,
1300 ) -> crate::Result<ApplicationHandle> {
1301 let mut reg_paths = Vec::new();
1302 let app_path = format!("{}{}", GATT_APP_PREFIX, Uuid::new_v4().as_simple());
1303 let app_path = dbus::Path::new(app_path).unwrap();
1304 log::trace!("Publishing application at {}", &app_path);
1305
1306 {
1307 let mut cr = inner.crossroads.lock().await;
1308
1309 let services = take(&mut self.services);
1310 reg_paths.push(app_path.clone());
1311 let om = cr.object_manager::<Self>();
1312 cr.insert(app_path.clone(), &[om], self);
1313
1314 for (service_idx, mut service) in services.into_iter().enumerate() {
1315 let chars = take(&mut service.characteristics);
1316
1317 let reg_service = RegisteredService::new(service);
1318 let service_path = format!("{}/service{}", &app_path, service_idx);
1319 let service_path = dbus::Path::new(service_path).unwrap();
1320 log::trace!("Publishing service at {}", &service_path);
1321 reg_paths.push(service_path.clone());
1322 cr.insert(service_path.clone(), &[inner.gatt_reg_service_token], Arc::new(reg_service));
1323
1324 for (char_idx, mut char) in chars.into_iter().enumerate() {
1325 let descs = take(&mut char.descriptors);
1326
1327 let reg_char = RegisteredCharacteristic::new(char, &inner.connection);
1328 let char_path = format!("{}/char{}", &service_path, char_idx);
1329 let char_path = dbus::Path::new(char_path).unwrap();
1330 log::trace!("Publishing characteristic at {}", &char_path);
1331 reg_paths.push(char_path.clone());
1332 cr.insert(char_path.clone(), &[inner.gatt_reg_characteristic_token], Arc::new(reg_char));
1333
1334 for (desc_idx, desc) in descs.into_iter().enumerate() {
1335 let reg_desc = RegisteredDescriptor::new(desc);
1336 let desc_path = format!("{}/desc{}", &char_path, desc_idx);
1337 let desc_path = dbus::Path::new(desc_path).unwrap();
1338 log::trace!("Publishing descriptor at {}", &desc_path);
1339 reg_paths.push(desc_path.clone());
1340 cr.insert(
1341 desc_path,
1342 &[inner.gatt_reg_characteristic_descriptor_token],
1343 Arc::new(reg_desc),
1344 );
1345 }
1346 }
1347 }
1348 }
1349
1350 log::trace!("Registering application at {}", &app_path);
1351 let proxy =
1352 Proxy::new(SERVICE_NAME, Adapter::dbus_path(&adapter_name)?, TIMEOUT, inner.connection.clone());
1353 let () = proxy
1354 .method_call(MANAGER_INTERFACE, "RegisterApplication", (app_path.clone(), PropMap::new()))
1355 .await?;
1356
1357 let (drop_tx, drop_rx) = oneshot::channel();
1358 let app_path_unreg = app_path.clone();
1359 tokio::spawn(async move {
1360 let _ = drop_rx.await;
1361
1362 log::trace!("Unregistering application at {}", &app_path_unreg);
1363 let _: std::result::Result<(), dbus::Error> =
1364 proxy.method_call(MANAGER_INTERFACE, "UnregisterApplication", (app_path_unreg,)).await;
1365
1366 let mut cr = inner.crossroads.lock().await;
1367 for reg_path in reg_paths.into_iter().rev() {
1368 log::trace!("Unpublishing {}", ®_path);
1369 let _: Option<Self> = cr.remove(®_path);
1370 }
1371 });
1372
1373 Ok(ApplicationHandle { name: app_path, _drop_tx: drop_tx })
1374 }
1375}
1376
1377pub struct ApplicationHandle {
1381 name: dbus::Path<'static>,
1382 _drop_tx: oneshot::Sender<()>,
1383}
1384
1385impl Drop for ApplicationHandle {
1386 fn drop(&mut self) {
1387 }
1389}
1390
1391impl fmt::Debug for ApplicationHandle {
1392 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1393 write!(f, "ApplicationHandle {{ {} }}", &self.name)
1394 }
1395}
1396
1397pub(crate) const GATT_PROFILE_PREFIX: &str = publish_path!("gatt/profile/");
1402
1403#[derive(Debug, Clone, Default)]
1410pub struct Profile {
1411 pub uuids: HashSet<Uuid>,
1413 #[doc(hidden)]
1414 pub _non_exhaustive: (),
1415}
1416
1417impl Profile {
1418 pub(crate) fn register_interface(cr: &mut Crossroads) -> IfaceToken<Self> {
1419 cr.register("org.bluez.GattProfile1", |ib: &mut IfaceBuilder<Self>| {
1420 cr_property!(ib, "UUIDs", p => {
1421 Some(p.uuids.iter().map(|uuid| uuid.to_string()).collect::<Vec<_>>())
1422 });
1423 })
1424 }
1425
1426 pub(crate) async fn register(
1427 self, inner: Arc<SessionInner>, adapter_name: Arc<String>,
1428 ) -> crate::Result<ProfileHandle> {
1429 let profile_path = format!("{}{}", GATT_PROFILE_PREFIX, Uuid::new_v4().as_simple());
1430 let profile_path = dbus::Path::new(profile_path).unwrap();
1431 log::trace!("Publishing profile at {}", &profile_path);
1432
1433 {
1434 let mut cr = inner.crossroads.lock().await;
1435 let om = cr.object_manager::<Self>();
1436 cr.insert(profile_path.clone(), &[inner.gatt_profile_token, om], self);
1437 }
1438
1439 log::trace!("Registering profile at {}", &profile_path);
1440 let proxy =
1441 Proxy::new(SERVICE_NAME, Adapter::dbus_path(&adapter_name)?, TIMEOUT, inner.connection.clone());
1442 let () = proxy
1443 .method_call(MANAGER_INTERFACE, "RegisterApplication", (profile_path.clone(), PropMap::new()))
1444 .await?;
1445
1446 let (drop_tx, drop_rx) = oneshot::channel();
1447 let profile_path_unreg = profile_path.clone();
1448 tokio::spawn(async move {
1449 let _ = drop_rx.await;
1450
1451 log::trace!("Unregistering profile at {}", &profile_path_unreg);
1452 let _: std::result::Result<(), dbus::Error> = proxy
1453 .method_call(MANAGER_INTERFACE, "UnregisterApplication", (profile_path_unreg.clone(),))
1454 .await;
1455
1456 log::trace!("Unpublishing profile at {}", &profile_path_unreg);
1457 let mut cr = inner.crossroads.lock().await;
1458 let _: Option<Self> = cr.remove(&profile_path_unreg);
1459 });
1460
1461 Ok(ProfileHandle { name: profile_path, _drop_tx: drop_tx })
1462 }
1463}
1464
1465#[must_use = "ProfileHandle must be held for profile to be published"]
1469pub struct ProfileHandle {
1470 name: dbus::Path<'static>,
1471 _drop_tx: oneshot::Sender<()>,
1472}
1473
1474impl Drop for ProfileHandle {
1475 fn drop(&mut self) {
1476 }
1478}
1479
1480impl fmt::Debug for ProfileHandle {
1481 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1482 write!(f, "ProfileHandle {{ {} }}", &self.name)
1483 }
1484}