summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomeo Disca <romeo.disca@gmail.com>2020-08-07 18:04:29 +0200
committerRomeo Disca <romeo.disca@gmail.com>2020-08-07 18:04:29 +0200
commit36bfd7c66ad1332eaedecde3b6273f4db0559103 (patch)
treecfbd4b39c1c0a8f2254284969c68fafa7fe60ecf
parent43664e4174d89a57f3679cdfdbebe2f706b56790 (diff)
chore: create simple command submitter
-rw-r--r--Cargo.lock312
-rw-r--r--Cargo.toml1
-rw-r--r--src/client.rs47
-rwxr-xr-xsrc/commands.rs99
-rw-r--r--src/events.rs72
-rw-r--r--src/main.rs10
6 files changed, 526 insertions, 15 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4462c9b..9513666 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,30 @@
# 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -12,6 +36,174 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -34,6 +226,12 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -61,16 +259,51 @@ dependencies = [
]
[[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]]
@@ -85,6 +318,41 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -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: F) -> Box<dyn FnMut(Event)>
where F: FnMut(Event) + 'static
@@ -9,16 +14,54 @@ pub fn event_handler<F>(f: F) -> Box<dyn FnMut(Event)>
}
pub struct FlicClient {
+ reader: Arc<TcpStream>,
+ writer: Arc<TcpStream>,
map: Vec<Box<dyn FnMut(Event)>>,
+ is_running: bool,
}
impl FlicClient {
- pub fn new() -> FlicClient {
- FlicClient{map: vec![]}
+ pub async fn new(conn: &str) -> Result<FlicClient> {
+ 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<dyn FnMut(Event)>) -> 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<String>,
@@ -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<dyn Error>> {
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(())
}