From 36bfd7c66ad1332eaedecde3b6273f4db0559103 Mon Sep 17 00:00:00 2001 From: Romeo Disca Date: Fri, 7 Aug 2020 18:04:29 +0200 Subject: chore: create simple command submitter --- Cargo.lock | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/client.rs | 47 ++++++++- src/commands.rs | 99 ++++++++++++++++++ src/events.rs | 72 +++++++++++-- src/main.rs | 10 +- 6 files changed, 526 insertions(+), 15 deletions(-) create mode 100755 src/commands.rs diff --git a/Cargo.lock b/Cargo.lock index 4462c9b..9513666 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,29 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "arc-swap" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "derivative" version = "2.1.1" @@ -11,6 +35,174 @@ dependencies = [ "syn", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "futures-core" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" + +[[package]] +name = "hermit-abi" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" +dependencies = [ + "libc", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10" + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "mio" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +dependencies = [ + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow 0.2.1", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-named-pipes" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" +dependencies = [ + "log", + "mio", + "miow 0.3.5", + "winapi 0.3.9", +] + +[[package]] +name = "mio-uds" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +dependencies = [ + "iovec", + "libc", + "mio", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "miow" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" +dependencies = [ + "socket2", + "winapi 0.3.9", +] + +[[package]] +name = "net2" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" +dependencies = [ + "cfg-if", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "num_enum" version = "0.4.3" @@ -33,6 +225,12 @@ dependencies = [ "syn", ] +[[package]] +name = "pin-project-lite" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -60,17 +258,52 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + [[package]] name = "serde" version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" +[[package]] +name = "signal-hook-registry" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" +dependencies = [ + "arc-swap", + "libc", +] + [[package]] name = "simpleclient" version = "0.1.0" dependencies = [ "num_enum", + "tokio", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "socket2" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.9", ] [[package]] @@ -84,6 +317,41 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tokio" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "iovec", + "lazy_static", + "libc", + "memchr", + "mio", + "mio-named-pipes", + "mio-uds", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "slab", + "tokio-macros", + "winapi 0.3.9", +] + +[[package]] +name = "tokio-macros" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "toml" version = "0.5.6" @@ -98,3 +366,47 @@ name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] diff --git a/Cargo.toml b/Cargo.toml index bdd05e1..de433c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ edition = "2018" [dependencies] num_enum = "0.4.2" +tokio = { version = "0.2", features = ["full"] } \ No newline at end of file diff --git a/src/client.rs b/src/client.rs index 3557df8..b6b681a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,6 +1,11 @@ +use std::sync::Arc; + +use tokio::io::*; +use tokio::net::TcpStream; use super::events::*; +use super::commands::Command; pub fn event_handler(f: F) -> Box where F: FnMut(Event) + 'static @@ -9,16 +14,54 @@ pub fn event_handler(f: F) -> Box } pub struct FlicClient { + reader: Arc, + writer: Arc, map: Vec>, + is_running: bool, } impl FlicClient { - pub fn new() -> FlicClient { - FlicClient{map: vec![]} + pub async fn new(conn: &str) -> Result { + match TcpStream::connect(conn).await { + Ok(stream) => { + let reader = Arc::new(stream); + let writer = reader.clone(); + + Ok(FlicClient{ + reader, + writer, + map: vec![], + is_running: true, + }) + } + Err(err) => Err(err) + } + } pub fn register_event_handler(mut self, event: Box) -> Self { self.map.push(event); self } + pub async fn listen(&mut self) { + while self.is_running { + if let Some(mut r) = Arc::get_mut(&mut self.reader) { + if let Ok(value) = r.read_u8().await { + for ref mut f in self.map.as_mut_slice() { + f(Event::read_event(value, &mut r)); + } + } + } + } + } + pub fn stop(&mut self) { + self.is_running = false; + } + + pub fn submit(&mut self, cmd: Command) -> Result<()> { + if let Some(mut w) = Arc::get_mut(&mut self.writer) { + cmd.write_command(&mut w)?; + } + Ok(()) + } } diff --git a/src/commands.rs b/src/commands.rs new file mode 100755 index 0000000..d84d9cd --- /dev/null +++ b/src/commands.rs @@ -0,0 +1,99 @@ + +use num_enum::TryFromPrimitive; +use num_enum::IntoPrimitive; +use tokio::io::*; +use tokio::net::TcpStream; + +use super::enums::LatencyMode; + +/// Commands + +pub enum Command { + GetInfo, + CreateScanner { + scan_id: u32, + }, + RemoveScanner { + scan_id: u32, + }, + CreateConnectionChannel { + conn_id: u32, + bd_addr: String, + latency_mode: LatencyMode, + auto_disconnect_time: i16, + }, + RemoveConnectionChannel { + conn_id: u32, + }, + ForceDisconnect { + bd_addr: String, + }, + ChangeModeParameters { + conn_id: u32, + latency_mode: LatencyMode, + auto_disconnect_time: i16, + }, + Ping { + ping_id: u32, + }, + GetButtonInfo { + bd_addr: String, + }, + CreateScanWizard { + scan_wizard_id: u32, + }, + CancelScanWizard { + scan_wizard_id: u32, + }, + DeleteButton { + bd_addr: String, + }, + CreateBatteryStatusListener { + listener_id: u32, + bd_addr: String, + }, + RemoveBatteryStatusListener { + listener_id: u32, + }, +} + +impl Command { + pub fn opcode(&self) -> u8 { + match self { + Self::GetInfo{..} => 0, + Self::CreateScanner{..} => 1, + Self::RemoveScanner{..} => 2, + Self::CreateConnectionChannel{..} => 3, + Self::RemoveConnectionChannel{..} => 4, + Self::ForceDisconnect{..} => 5, + Self::ChangeModeParameters{..} => 6, + Self::Ping{..} => 7, + Self::GetButtonInfo{..} => 8, + Self::CreateScanWizard{..} => 9, + Self::CancelScanWizard{..} => 10, + Self::DeleteButton{..} => 11, + Self::CreateBatteryStatusListener{..} => 12, + Self::RemoveBatteryStatusListener{..} => 13, + } + } + pub fn write_command(&self, writer: &mut TcpStream) -> Result<()> { + match self { + Self::GetInfo{..} => 0, + Self::CreateScanner{..} => 1, + Self::RemoveScanner{..} => 2, + Self::CreateConnectionChannel{..} => 3, + Self::RemoveConnectionChannel{..} => 4, + Self::ForceDisconnect{..} => 5, + Self::ChangeModeParameters{..} => 6, + Self::Ping{..} => 7, + Self::GetButtonInfo{..} => 8, + Self::CreateScanWizard{..} => 9, + Self::CancelScanWizard{..} => 10, + Self::DeleteButton{..} => 11, + Self::CreateBatteryStatusListener{..} => 12, + Self::RemoveBatteryStatusListener{..} => 13, + }; + + Ok(()) + } +} \ No newline at end of file diff --git a/src/events.rs b/src/events.rs index aa53280..ac00472 100644 --- a/src/events.rs +++ b/src/events.rs @@ -1,11 +1,14 @@ +use tokio::net::TcpStream; + use super::enums::*; #[allow(dead_code)] #[derive(Debug, PartialEq, Eq, Clone)] pub enum Event { + CorruptEvent, + AdvertisementPacket { - opcode: u8, scan_id: u32, bd_addr: String, name: String, @@ -33,7 +36,25 @@ pub enum Event { removed_reason: RemovedReason, }, - ButtonEvent { + ButtonUpOrDown{ + conn_id: u32, + click_type: ClickType, + was_queued: bool, + time_diff: i32, + }, + ButtonClickOrHold{ + conn_id: u32, + click_type: ClickType, + was_queued: bool, + time_diff: i32, + }, + ButtonSingleOrDoubleClick{ + conn_id: u32, + click_type: ClickType, + was_queued: bool, + time_diff: i32, + }, + ButtonSingleOrDoubleClickOrHold{ conn_id: u32, click_type: ClickType, was_queued: bool, @@ -41,12 +62,10 @@ pub enum Event { }, NewVerifiedButton { - opcode: u8, bd_addr: String, }, GetInfoResponse { - opcode: u8, bluetooth_controller_state: BluetoothControllerState, my_bd_addr: String, my_bd_addr_type: BdAddrType, @@ -58,27 +77,22 @@ pub enum Event { }, NoSpaceForNewConnection { - opcode: u8, max_concurrently_connected_buttons: u8, }, GotSpaceForNewConnection { - opcode: u8, max_concurrently_connected_buttons: u8, }, BluetoothControllerStateChange { - opcode: u8, state: BluetoothControllerState, }, PingResponse { - opcode: u8, ping_id: u32, }, GetButtonInfoResponse { - opcode: u8, bd_addr: String, uuid: String, color: Option, @@ -105,15 +119,51 @@ pub enum Event { }, ButtonDeleted { - opcode: u8, bd_addr: String, deleted_by_this_client: bool, }, BatteryStatus { - opcode: u8, listener_id: u32, battery_percentage: i8, timestamp: u64, }, } + +impl Event { + pub fn opcode(&self) -> u8 { + match self { + Self::CorruptEvent => 255, + Self::AdvertisementPacket{..} => 0, + Self::CreateConnectionChannelResponse{..} => 1, + Self::ConnectionStatusChanged{..} => 2, + Self::ConnectionChannelRemoved{..} => 3, + Self::ButtonUpOrDown{..} => 4, + Self::ButtonClickOrHold{..} => 5, + Self::ButtonSingleOrDoubleClick{..} => 6, + Self::ButtonSingleOrDoubleClickOrHold{..} => 7, + Self::NewVerifiedButton{..} => 8, + Self::GetInfoResponse{..} => 9, + Self::NoSpaceForNewConnection{..} => 10, + Self::GotSpaceForNewConnection{..} => 11, + Self::BluetoothControllerStateChange{..} => 12, + Self::PingResponse{..} => 13, + Self::GetButtonInfoResponse{..} => 14, + Self::ScanWizardFoundPrivateButton{..} => 15, + Self::ScanWizardFoundPublicButton{..} => 16, + Self::ScanWizardButtonConnected{..} => 17, + Self::ScanWizardCompleted{..} => 18, + Self::ButtonDeleted{..} => 19, + Self::BatteryStatus{..} => 20, + } + } + + pub fn read_event(opcode: u8, reader: &mut TcpStream) -> Event { + match opcode { + 13 => Self::PingResponse{ping_id: 8}, + _ => Self::CorruptEvent, + } + } + +} + diff --git a/src/main.rs b/src/main.rs index fff75ce..bcefc75 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,23 @@ mod enums; mod events; +mod commands; mod client; +use std::error::Error; + use client::*; -fn main() { +#[tokio::main] +async fn main() -> Result<(), Box> { let event = event_handler(|event| { println!("ping response: {:?}", event); }); let event2 = event_handler(|event| { println!("ping response: {:?}", event); }); - let _client = FlicClient::new() + let _client = FlicClient::new("127.0.0.1:5551").await? .register_event_handler(event) .register_event_handler(event2) ; + + Ok(()) } -- cgit v1.2.3