summaryrefslogtreecommitdiffstats
path: root/src
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 /src
parent43664e4174d89a57f3679cdfdbebe2f706b56790 (diff)
chore: create simple command submitter
Diffstat (limited to 'src')
-rw-r--r--src/client.rs47
-rwxr-xr-xsrc/commands.rs99
-rw-r--r--src/events.rs72
-rw-r--r--src/main.rs10
4 files changed, 213 insertions, 15 deletions
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(())
}