diff options
author | Romeo Disca <romeo.disca@gmail.com> | 2020-08-07 18:04:29 +0200 |
---|---|---|
committer | Romeo Disca <romeo.disca@gmail.com> | 2020-08-07 18:04:29 +0200 |
commit | 36bfd7c66ad1332eaedecde3b6273f4db0559103 (patch) | |
tree | cfbd4b39c1c0a8f2254284969c68fafa7fe60ecf /src | |
parent | 43664e4174d89a57f3679cdfdbebe2f706b56790 (diff) |
chore: create simple command submitter
Diffstat (limited to 'src')
-rw-r--r-- | src/client.rs | 47 | ||||
-rwxr-xr-x | src/commands.rs | 99 | ||||
-rw-r--r-- | src/events.rs | 72 | ||||
-rw-r--r-- | src/main.rs | 10 |
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(()) } |