1use std::sync::Arc;
9use std::sync::mpsc;
10use std::cell::Cell;
11use std::thread;
12
13use dbus_tree as tree;
14use dbus::Path;
15use dbus_tree::{Interface, Signal, MTFn, Access, MethodErr, EmitsChangedSignal};
16use dbus::ffidisp::Connection;
17
18#[derive(Debug)]
20struct Device {
21 description: String,
22 path: Path<'static>,
23 index: i32,
24 online: Cell<bool>,
25 checking: Cell<bool>,
26}
27
28#[derive(Copy, Clone, Default, Debug)]
31struct TData;
32impl tree::DataType for TData {
33 type Tree = ();
34 type ObjectPath = Arc<Device>;
35 type Property = ();
36 type Interface = ();
37 type Method = ();
38 type Signal = ();
39}
40
41
42impl Device {
43 fn new_bogus(index: i32) -> Device {
45 Device {
46 description: format!("This is device {}, which is {}.", index,
47 ["totally awesome", "really fancy", "still going strong"][(index as usize) % 3]),
48 path: format!("/Device{}", index).into(),
49 index: index,
50 online: Cell::new(index % 2 == 0),
51 checking: Cell::new(false),
52 }
53 }
54}
55
56fn create_iface(check_complete_s: mpsc::Sender<i32>) -> (Interface<MTFn<TData>, TData>, Arc<Signal<TData>>) {
58 let f = tree::Factory::new_fn();
59
60 let check_complete = Arc::new(f.signal("CheckComplete", ()));
61
62 (f.interface("com.example.dbus.rs.device", ())
63 .add_p(f.property::<bool,_>("online", ())
65 .access(Access::ReadWrite)
66 .on_get(|i, m| {
67 let dev: &Arc<Device> = m.path.get_data();
68 i.append(dev.online.get());
69 Ok(())
70 })
71 .on_set(|i, m| {
72 let dev: &Arc<Device> = m.path.get_data();
73 let b: bool = i.read()?;
74 if b && dev.checking.get() {
75 return Err(MethodErr::failed(&"Device currently under check, cannot bring online"))
76 }
77 dev.online.set(b);
78 Ok(())
79 })
80 )
81 .add_p(f.property::<bool,_>("checking", ())
83 .emits_changed(EmitsChangedSignal::False)
84 .on_get(|i, m| {
85 let dev: &Arc<Device> = m.path.get_data();
86 i.append(dev.checking.get());
87 Ok(())
88 })
89 )
90 .add_p(f.property::<&str,_>("description", ())
92 .emits_changed(EmitsChangedSignal::Const)
93 .on_get(|i, m| {
94 let dev: &Arc<Device> = m.path.get_data();
95 i.append(&dev.description);
96 Ok(())
97 })
98 )
99 .add_m(f.method("check", (), move |m| {
101 let dev: &Arc<Device> = m.path.get_data();
102 if dev.checking.get() {
103 return Err(MethodErr::failed(&"Device currently under check, cannot start another check"))
104 }
105 if dev.online.get() {
106 return Err(MethodErr::failed(&"Device is currently online, cannot start check"))
107 }
108 dev.checking.set(true);
109
110 let devindex = dev.index;
112 let ch = check_complete_s.clone();
113 thread::spawn(move || {
114
115 use std::time::Duration;
117 thread::sleep(Duration::from_secs(15));
118
119 ch.send(devindex).unwrap();
121 });
122 Ok(vec!(m.msg.method_return()))
123 }))
124 .add_s(check_complete.clone())
126 , check_complete)
127}
128
129fn create_tree(devices: &[Arc<Device>], iface: &Arc<Interface<MTFn<TData>, TData>>)
130 -> tree::Tree<MTFn<TData>, TData> {
131
132 let f = tree::Factory::new_fn();
133 let mut tree = f.tree(());
134 for dev in devices {
135 tree = tree.add(f.object_path(dev.path.clone(), dev.clone())
136 .introspectable()
137 .add(iface.clone())
138 );
139 }
140 tree
141}
142
143fn run() -> Result<(), Box<dyn std::error::Error>> {
144 let devices: Vec<Arc<Device>> = (0..10).map(|i| Arc::new(Device::new_bogus(i))).collect();
146
147 let (check_complete_s, check_complete_r) = mpsc::channel::<i32>();
149 let (iface, sig) = create_iface(check_complete_s);
150 let tree = create_tree(&devices, &Arc::new(iface));
151
152 let c = Connection::new_session()?;
154 c.register_name("com.example.dbus.rs.advancedserverexample", 0)?;
155 tree.set_registered(&c, true)?;
156
157 c.add_handler(tree);
159 loop {
160 c.incoming(1000).next();
163
164 if let Ok(idx) = check_complete_r.try_recv() {
166 let dev = &devices[idx as usize];
167 dev.checking.set(false);
168 c.send(sig.msg(&dev.path, &"com.example.dbus.rs.device".into())).map_err(|_| "Sending DBus signal failed")?;
169 }
170 }
171}
172
173fn main() {
174 if let Err(e) = run() {
175 println!("{}", e);
176 }
177}