1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
//! pfly_rust is a crate to interact with the projectFly X-Plane IPC service. //! //! This was originally made to create a Linux supported alternative to the native X-Plane projectFly plugin, which is from a project to port projectFly over to Linux. //! //! Creating a connection is super easy, calling [`init`] will give you a socket object that is bonded and connected to projectFly. //! You can then use [`send_message`] to send a message to projectFly with the structure of [`PflyIpcData`]. //! //! [`init`]: fn.init.html //! [`send_message`]: fn.send_message.html //! [`PflyIpcData`]: struct.PflyIpcData.html use serde::Serialize; use socket2::{Domain, SockAddr, Socket, Type}; /// Connects to the projectFly Unix socket at `/tmp/pf.sock`. /// /// Returns said socket for future use. /// /// # Example /// /// ``` /// let pfly_socket = pfly_rust::init(); /// ``` pub fn init() -> Socket { let pfly_socket = Socket::new(Domain::unix(), Type::stream(), None).unwrap(); let pfly_socket_addr = &SockAddr::unix("/tmp/pf.sock").unwrap(); if pfly_socket.connect(pfly_socket_addr).is_err() { panic!("Could not connect to projectFly socket!") } return pfly_socket; } /// Sends a message to the projectFly socket with a [`PflyIpcData`] payload converted into u8. /// /// Returns false if any errors ocurred when sending /// /// # Arguments /// * `pfly_socket` - The socket object from init() /// * `data` - Information to be sent in the form of [`PflyIpcData`] /// /// # Example /// /// ``` /// let pfly_socket = pfly_rust::init(); /// /// pfly_rust::send_message(pfly_socket, pfly_rust::PflyIpcData{ /// altitude: 569, /// agl: 0, /// groundspeed: 0, /// ias: 0, /// headingTrue: 0, /// headingMagnetic: 0, /// latitude: 43.6772222, /// longitude: -79.6305556, /// verticalSpeed: 0, /// landingVerticalSpeed: 0, /// gForce: 1000, // Divided by 1000 by projectFly /// fuel: 20000, /// transponder: 1425, /// bridgeType: 3, // From projectFly: bridgeTypes = ['simconnect', 'fsuipc', 'if', 'xplane'] /// isOnGround: 1, /// isSlew: 0, /// isPaused: 0, /// pitch: 0, /// roll: 0, /// time: 0, // This is calculated by projectFly /// fps: 120, /// aircraftType: "B77W" // Unused by projectFly, still required just in case /// }); /// ``` /// /// [`PflyIpcData`]: struct.PflyIpcData.html pub fn send_message(pfly_socket: Socket, data: PflyIpcData) -> bool { let payload: Vec<u8> = bincode::serialize(&data).unwrap(); return pfly_socket.send(payload.as_ref()).is_ok(); } /// Structure of data that projectFly expects over it's X-Plane IPC connection. /// /// As found in `/src/app/providers/flightsim.service.ts` of the projectFly source. #[allow(non_snake_case)] #[derive(Serialize)] pub struct PflyIpcData { pub altitude: i32, pub agl: i32, pub groundspeed: i32, pub ias: i32, pub headingTrue: i32, pub headingMagnetic: i32, pub latitude: f64, pub longitude: f64, pub verticalSpeed: i32, pub landingVerticalSpeed: i32, pub gForce: i32, pub fuel: i32, pub transponder: i32, pub bridgeType: u8, pub isOnGround: u8, pub isSlew: u8, pub isPaused: u8, pub pitch: i32, pub roll: i32, pub time: i32, // This is calculated at projectFly pub fps: i32, pub aircraftType: &'static str, // This isn't applied on the projectFly side for some reason, still adding it just incase } #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }