|
| 1 | +use anyhow::Result; |
| 2 | +use serde::{Deserialize, Serialize}; |
| 3 | +use std::io::{Read, Write}; |
| 4 | +use std::os::unix::net::UnixStream; |
| 5 | +use std::process; |
| 6 | + |
| 7 | +/// Minimal representation of the Controller type for the example |
| 8 | +#[derive(Serialize, Deserialize, Debug, Clone)] |
| 9 | +struct Controller { |
| 10 | + name: String, |
| 11 | + version: Option<String>, |
| 12 | + pid: i64, |
| 13 | + description: Option<String>, |
| 14 | + website: Option<String>, |
| 15 | + capabilities: Vec<String>, |
| 16 | + interested_devices: Vec<String>, |
| 17 | +} |
| 18 | + |
| 19 | +#[derive(Serialize)] |
| 20 | +struct RegisterArgs { |
| 21 | + controller: Controller, |
| 22 | +} |
| 23 | + |
| 24 | +#[derive(Serialize)] |
| 25 | +struct UnregisterArgs { |
| 26 | + pid: i64, |
| 27 | +} |
| 28 | + |
| 29 | +#[derive(Serialize)] |
| 30 | +struct VarlinkRequest<T> { |
| 31 | + method: String, |
| 32 | + parameters: T, |
| 33 | +} |
| 34 | + |
| 35 | +fn main() -> Result<()> { |
| 36 | + let socket_path = "/run/contextd/public/contextd.socket"; |
| 37 | + let mut stream = UnixStream::connect(socket_path)?; |
| 38 | + |
| 39 | + let pid = process::id() as i64; |
| 40 | + let hint = Controller { |
| 41 | + name: "Rust Example Agent".to_string(), |
| 42 | + version: Some("0.1.0".to_string()), |
| 43 | + pid, |
| 44 | + description: Some("Cooperative hardware manager example in Rust".to_string()), |
| 45 | + website: None, |
| 46 | + capabilities: vec!["rust".to_string(), "demo".to_string()], |
| 47 | + interested_devices: vec!["/dev/hidraw0".to_string()], |
| 48 | + }; |
| 49 | + |
| 50 | + println!("Registering hint for PID {}...", pid); |
| 51 | + |
| 52 | + // Register |
| 53 | + let req = VarlinkRequest { |
| 54 | + method: "com.performativenonsense.contextd.RegisterController".to_string(), |
| 55 | + parameters: RegisterArgs { controller: hint }, |
| 56 | + }; |
| 57 | + |
| 58 | + let mut payload = serde_json::to_vec(&req)?; |
| 59 | + payload.push(0); // Varlink uses null-terminator for messages |
| 60 | + stream.write_all(&payload)?; |
| 61 | + |
| 62 | + // Read the response (Varlink requires reading the response to ensure the call completed) |
| 63 | + let mut buf = [0u8; 1024]; |
| 64 | + let n = stream.read(&mut buf)?; |
| 65 | + println!("Response: {}", String::from_utf8_lossy(&buf[..n]).trim_end_matches('\0')); |
| 66 | + |
| 67 | + println!("\nRegistered successfully. You can verify this by running:"); |
| 68 | + println!(" varlinkctl call unix:{} com.performativenonsense.contextd.ListControllers", socket_path); |
| 69 | + |
| 70 | + println!("\nPress Enter to unregister and exit..."); |
| 71 | + let mut input = String::new(); |
| 72 | + std::io::stdin().read_line(&mut input)?; |
| 73 | + |
| 74 | + // Unregister cleanly |
| 75 | + let mut stream = UnixStream::connect(socket_path)?; |
| 76 | + let req = VarlinkRequest { |
| 77 | + method: "com.performativenonsense.contextd.UnregisterController".to_string(), |
| 78 | + parameters: UnregisterArgs { pid }, |
| 79 | + }; |
| 80 | + let mut payload = serde_json::to_vec(&req)?; |
| 81 | + payload.push(0); |
| 82 | + stream.write_all(&payload)?; |
| 83 | + |
| 84 | + println!("Unregistered. Goodbye!"); |
| 85 | + |
| 86 | + Ok(()) |
| 87 | +} |
0 commit comments