summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomeo Disca <romeo.disca@gmail.com>2020-08-19 00:34:56 +0200
committerRomeo Disca <romeo.disca@gmail.com>2020-08-19 00:35:44 +0200
commitfc00a175dda64108f4a26e4b846bf0ae9e2eabe3 (patch)
tree1287e6dfc1aba14ac55a1644be7fcf7f166f8b31
parenta14cc3f38b67e6054bdbff8aff7c60967f342194 (diff)
downloadflicbtn-fc00a175dda64108f4a26e4b846bf0ae9e2eabe3.tar.gz
flicbtn-fc00a175dda64108f4a26e4b846bf0ae9e2eabe3.tar.xz
chore: create simple client
-rwxr-xr-x[-rw-r--r--].gitignore0
-rwxr-xr-x[-rw-r--r--]Cargo.lock0
-rwxr-xr-x[-rw-r--r--]Cargo.toml0
-rwxr-xr-x[-rw-r--r--]examples/ping.rs0
-rwxr-xr-xexamples/simpleclient.rs107
-rwxr-xr-x[-rw-r--r--]src/client.rs0
-rwxr-xr-x[-rw-r--r--]src/commands/mod.rs0
-rwxr-xr-x[-rw-r--r--]src/commands/stream_mapper.rs384
-rwxr-xr-x[-rw-r--r--]src/enums.rs198
-rwxr-xr-x[-rw-r--r--]src/events/mod.rs0
-rwxr-xr-x[-rw-r--r--]src/events/stream_mapper.rs0
-rwxr-xr-x[-rw-r--r--]src/lib.rs3
12 files changed, 400 insertions, 292 deletions
diff --git a/.gitignore b/.gitignore
index ea8c4bf..ea8c4bf 100644..100755
--- a/.gitignore
+++ b/.gitignore
diff --git a/Cargo.lock b/Cargo.lock
index f9b2e50..f9b2e50 100644..100755
--- a/Cargo.lock
+++ b/Cargo.lock
diff --git a/Cargo.toml b/Cargo.toml
index 69d3fc1..69d3fc1 100644..100755
--- a/Cargo.toml
+++ b/Cargo.toml
diff --git a/examples/ping.rs b/examples/ping.rs
index 4a6a7cb..4a6a7cb 100644..100755
--- a/examples/ping.rs
+++ b/examples/ping.rs
diff --git a/examples/simpleclient.rs b/examples/simpleclient.rs
new file mode 100755
index 0000000..52b4300
--- /dev/null
+++ b/examples/simpleclient.rs
@@ -0,0 +1,107 @@
+
+
+use std::io::*;
+use std::sync::Arc;
+
+use flicbtn::*;
+
+#[tokio::main]
+async fn main() -> Result<()> {
+
+ let event = event_handler(|event| { println!("ping response: {:?}", event); });
+
+ let client = FlicClient::new("127.0.0.1:5551").await?
+ .register_event_handler(event).await
+ ;
+ let client1 = Arc::new(client);
+ let client2 = client1.clone();
+
+ let button = "80:e4:da:76:fa:55";
+
+ let mut scan_wizard_id = 0;
+ let mut conn_id = 0;
+
+ let cmd = tokio::spawn(async move {
+
+ println!("===============================================");
+ println!("*** Hello to the Flic2 Button Simple Client ***");
+ println!("===============================================");
+ client1.submit(Command::GetInfo).await;
+ println!("");
+
+ loop {
+
+ show_commands();
+
+ println!("");
+ print!("-- Choose: ");
+
+ let _ = stdout().flush();
+
+ let mut input = String::new();
+ stdin().read_line(&mut input).expect("Did not enter correct string!");
+
+ println!("[{}]", &input.as_str()[0..input.len()-2]);
+
+ match &input.as_str()[..input.len()-2] {
+ "X" => break,
+ "1" => {
+ println!("-- start scan wizard");
+ scan_wizard_id += 1;
+ client1.submit(Command::CreateScanWizard{scan_wizard_id}).await;
+ }
+ "2" => {
+ println!("-- cancel scan wizard");
+ client1.submit(Command::CancelScanWizard{scan_wizard_id}).await;
+ //scan_wizard_id -= 1;
+ }
+ "3" => {
+ println!("-- create connection channel");
+ conn_id += 1;
+ client1.submit(Command::CreateConnectionChannel{
+ conn_id,
+ bd_addr: button.to_string(),
+ latency_mode: LatencyMode::NormalLatency,
+ auto_disconnect_time: 11111_i16,
+ }).await;
+ }
+ "4" => {
+ println!("-- remove connection channel");
+ client1.submit(Command::RemoveConnectionChannel{
+ conn_id,
+ }).await;
+ //conn_id -= 1;
+ }
+ "5" => {
+ println!("-- button info");
+ client1.submit(Command::GetButtonInfo{bd_addr: button.to_string()}).await;
+ }
+ _ => {
+ println!("-- unknown command");
+ }
+ }
+
+ println!("");
+ }
+
+ client1.stop().await;
+ });
+ let lst = tokio::spawn(async move {
+ client2.listen().await;
+ println!("stop");
+ });
+
+ lst.await?;
+ cmd.await?;
+
+ Ok(())
+}
+
+fn show_commands() {
+ println!("1) Start Scan Wizard");
+ println!("2) Cancel Scan Wizard");
+ println!("3) Create Connection Channel");
+ println!("4) Remove Connection Channel");
+ println!("5) Get Button Info");
+ println!("X) End");
+} \ No newline at end of file
diff --git a/src/client.rs b/src/client.rs
index a1a63f7..a1a63f7 100644..100755
--- a/src/client.rs
+++ b/src/client.rs
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index e2b886b..e2b886b 100644..100755
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
diff --git a/src/commands/stream_mapper.rs b/src/commands/stream_mapper.rs
index 2b6f612..4b13bc8 100644..100755
--- a/src/commands/stream_mapper.rs
+++ b/src/commands/stream_mapper.rs
@@ -1,192 +1,192 @@
-
-use regex::Regex;
-
-use std::collections::VecDeque;
-use std::collections::vec_deque::Drain;
-use std::convert::TryInto;
-
-use super::*;
-
-pub struct CommandToByteMapper {
- buffer: VecDeque<u8>,
-}
-impl CommandToByteMapper {
-
- pub fn new() -> CommandToByteMapper {
- CommandToByteMapper{ buffer: VecDeque::new() }
- }
-
- pub fn map(&mut self, command: Command) -> Drain<u8> {
- self.clear_buffer();
-
- self.write_u8(command.opcode());
- match command {
- Command::GetInfo => {},
- Command::CreateScanner {
- scan_id,
- } => {
-
- self.write_u32(scan_id);
- },
- Command::RemoveScanner {
- scan_id,
- } => {
-
- self.write_u32(scan_id);
- },
- Command::CreateConnectionChannel {
- conn_id,
- bd_addr,
- latency_mode,
- auto_disconnect_time,
- } => {
-
- self.write_u32(conn_id);
- self.write_bdaddr(&bd_addr[..]);
- if let Ok(latency_mode) = latency_mode.try_into() {
- self.write_u8(latency_mode);
- }
- self.write_i16(auto_disconnect_time);
- },
- Command::RemoveConnectionChannel {
- conn_id,
- } => {
-
- self.write_u32(conn_id);
- },
- Command::ForceDisconnect {
- bd_addr,
- } => {
-
- self.write_bdaddr(&bd_addr[..]);
- },
- Command::ChangeModeParameters {
- conn_id,
- latency_mode,
- auto_disconnect_time,
- } => {
-
- self.write_u32(conn_id);
- if let Ok(latency_mode) = latency_mode.try_into() {
- self.write_u8(latency_mode);
- }
- self.write_i16(auto_disconnect_time);
- },
- Command::Ping {
- ping_id,
- } => {
-
- self.write_u32(ping_id);
- },
- Command::GetButtonInfo {
- bd_addr,
- } => {
-
- self.write_bdaddr(&bd_addr[..]);
- },
- Command::CreateScanWizard {
- scan_wizard_id,
- } => {
-
- self.write_u32(scan_wizard_id);
- },
- Command::CancelScanWizard {
- scan_wizard_id,
- } => {
-
- self.write_u32(scan_wizard_id);
- },
- Command::DeleteButton {
- bd_addr,
- } => {
-
- self.write_bdaddr(&bd_addr[..]);
- },
- Command::CreateBatteryStatusListener {
- listener_id,
- bd_addr,
- } => {
-
- self.write_u32(listener_id);
- self.write_bdaddr(&bd_addr[..]);
- },
- Command::RemoveBatteryStatusListener {
- listener_id,
- } => {
-
- self.write_u32(listener_id);
- },
- }
-
- self.prepend_size();
-
- self.buffer.drain(..)
- }
-
- fn clear_buffer(&mut self) {
- self.buffer.drain(..);
- }
-
- fn prepend_size(&mut self) {
- let len = self.buffer.len();
- self.buffer.push_front((len >> 8) as u8);
- self.buffer.push_front((len & 255) as u8);
- }
- fn write_u8(&mut self, value: u8) {
- let mut buf = vec![value].into_iter().collect();
- self.buffer.append(&mut buf);
- }
-/*
- fn write_bool(&mut self, value: bool) {
- if value {
- self.write_u8(1);
- }
- else {
- self.write_u8(0);
- }
- }
-*/
- fn write_u16(&mut self, value: u16) {
- self.write_u8(value as u8);
- self.write_u8((value >> 8) as u8);
- }
- fn write_i16(&mut self, value: i16) {
- self.write_u8(value as u8);
- self.write_u8((value >> 8) as u8);
- }
- fn write_u32(&mut self, value: u32) {
- self.write_u16(value as u16);
- self.write_u16((value >> 16) as u16);
- }
-/*
- fn write_i32(&mut self, value: i32) {
- self.write_i16(value as i16);
- self.write_i16((value >> 16) as i16);
- }
-*/
- fn write_bdaddr(&mut self, str: &str) {
- let re = Regex::new(r"([0-9a-z]{2}:){5}[0-9a-z]{2}").unwrap();
- if re.is_match(str) {
- if let Some(b) = hex_to_u8(&str[15..]) { self.write_u8(b); }
- if let Some(b) = hex_to_u8(&str[12..]) { self.write_u8(b); }
- if let Some(b) = hex_to_u8(&str[ 9..]) { self.write_u8(b); }
- if let Some(b) = hex_to_u8(&str[ 6..]) { self.write_u8(b); }
- if let Some(b) = hex_to_u8(&str[ 3..]) { self.write_u8(b); }
- if let Some(b) = hex_to_u8(&str[ ..]) { self.write_u8(b); }
- }
- }
-
-}
-
-fn hex_to_u8(buffer: &str) -> Option<u8> {
- let mut char_indices = buffer.char_indices();
- match (char_indices.next(), char_indices.next()) {
- (Some((0, upper)), Some((1, lower))) => {
- let mut b = 0u8;
- if let Some(v) = upper.to_digit(16) { b += (v as u8) << 4; }
- if let Some(v) = lower.to_digit(16) { b += v as u8; }
- Some(b)
- },
- _ => None,
- }
-}
+
+use regex::Regex;
+
+use std::collections::VecDeque;
+use std::collections::vec_deque::Drain;
+use std::convert::TryInto;
+
+use super::*;
+
+pub struct CommandToByteMapper {
+ buffer: VecDeque<u8>,
+}
+impl CommandToByteMapper {
+
+ pub fn new() -> CommandToByteMapper {
+ CommandToByteMapper{ buffer: VecDeque::new() }
+ }
+
+ pub fn map(&mut self, command: Command) -> Drain<u8> {
+ self.clear_buffer();
+
+ self.write_u8(command.opcode());
+ match command {
+ Command::GetInfo => {},
+ Command::CreateScanner {
+ scan_id,
+ } => {
+
+ self.write_u32(scan_id);
+ },
+ Command::RemoveScanner {
+ scan_id,
+ } => {
+
+ self.write_u32(scan_id);
+ },
+ Command::CreateConnectionChannel {
+ conn_id,
+ bd_addr,
+ latency_mode,
+ auto_disconnect_time,
+ } => {
+
+ self.write_u32(conn_id);
+ self.write_bdaddr(&bd_addr[..]);
+ if let Ok(latency_mode) = latency_mode.try_into() {
+ self.write_u8(latency_mode);
+ }
+ self.write_i16(auto_disconnect_time);
+ },
+ Command::RemoveConnectionChannel {
+ conn_id,
+ } => {
+
+ self.write_u32(conn_id);
+ },
+ Command::ForceDisconnect {
+ bd_addr,
+ } => {
+
+ self.write_bdaddr(&bd_addr[..]);
+ },
+ Command::ChangeModeParameters {
+ conn_id,
+ latency_mode,
+ auto_disconnect_time,
+ } => {
+
+ self.write_u32(conn_id);
+ if let Ok(latency_mode) = latency_mode.try_into() {
+ self.write_u8(latency_mode);
+ }
+ self.write_i16(auto_disconnect_time);
+ },
+ Command::Ping {
+ ping_id,
+ } => {
+
+ self.write_u32(ping_id);
+ },
+ Command::GetButtonInfo {
+ bd_addr,
+ } => {
+
+ self.write_bdaddr(&bd_addr[..]);
+ },
+ Command::CreateScanWizard {
+ scan_wizard_id,
+ } => {
+
+ self.write_u32(scan_wizard_id);
+ },
+ Command::CancelScanWizard {
+ scan_wizard_id,
+ } => {
+
+ self.write_u32(scan_wizard_id);
+ },
+ Command::DeleteButton {
+ bd_addr,
+ } => {
+
+ self.write_bdaddr(&bd_addr[..]);
+ },
+ Command::CreateBatteryStatusListener {
+ listener_id,
+ bd_addr,
+ } => {
+
+ self.write_u32(listener_id);
+ self.write_bdaddr(&bd_addr[..]);
+ },
+ Command::RemoveBatteryStatusListener {
+ listener_id,
+ } => {
+
+ self.write_u32(listener_id);
+ },
+ }
+
+ self.prepend_size();
+
+ self.buffer.drain(..)
+ }
+
+ fn clear_buffer(&mut self) {
+ self.buffer.drain(..);
+ }
+
+ fn prepend_size(&mut self) {
+ let len = self.buffer.len();
+ self.buffer.push_front((len >> 8) as u8);
+ self.buffer.push_front((len & 255) as u8);
+ }
+ fn write_u8(&mut self, value: u8) {
+ let mut buf = vec![value].into_iter().collect();
+ self.buffer.append(&mut buf);
+ }
+/*
+ fn write_bool(&mut self, value: bool) {
+ if value {
+ self.write_u8(1);
+ }
+ else {
+ self.write_u8(0);
+ }
+ }
+*/
+ fn write_u16(&mut self, value: u16) {
+ self.write_u8(value as u8);
+ self.write_u8((value >> 8) as u8);
+ }
+ fn write_i16(&mut self, value: i16) {
+ self.write_u8(value as u8);
+ self.write_u8((value >> 8) as u8);
+ }
+ fn write_u32(&mut self, value: u32) {
+ self.write_u16(value as u16);
+ self.write_u16((value >> 16) as u16);
+ }
+/*
+ fn write_i32(&mut self, value: i32) {
+ self.write_i16(value as i16);
+ self.write_i16((value >> 16) as i16);
+ }
+*/
+ fn write_bdaddr(&mut self, str: &str) {
+ let re = Regex::new(r"([0-9a-z]{2}:){5}[0-9a-z]{2}").unwrap();
+ if re.is_match(str) {
+ if let Some(b) = hex_to_u8(&str[15..]) { self.write_u8(b); }
+ if let Some(b) = hex_to_u8(&str[12..]) { self.write_u8(b); }
+ if let Some(b) = hex_to_u8(&str[ 9..]) { self.write_u8(b); }
+ if let Some(b) = hex_to_u8(&str[ 6..]) { self.write_u8(b); }
+ if let Some(b) = hex_to_u8(&str[ 3..]) { self.write_u8(b); }
+ if let Some(b) = hex_to_u8(&str[ ..]) { self.write_u8(b); }
+ }
+ }
+
+}
+
+fn hex_to_u8(buffer: &str) -> Option<u8> {
+ let mut char_indices = buffer.char_indices();
+ match (char_indices.next(), char_indices.next()) {
+ (Some((0, upper)), Some((1, lower))) => {
+ let mut b = 0u8;
+ if let Some(v) = upper.to_digit(16) { b += (v as u8) << 4; }
+ if let Some(v) = lower.to_digit(16) { b += v as u8; }
+ Some(b)
+ },
+ _ => None,
+ }
+}
diff --git a/src/enums.rs b/src/enums.rs
index 64284a2..83fe016 100644..100755
--- a/src/enums.rs
+++ b/src/enums.rs
@@ -1,99 +1,99 @@
-
-#![allow(dead_code)]
-
-use num_enum::TryFromPrimitive;
-use num_enum::IntoPrimitive;
-
-// Enums
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum CreateConnectionChannelError {
- NoError,
- MaxPendingConnectionsReached,
-}
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum ConnectionStatus {
- Disconnected,
- Connected,
- Ready,
-}
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum DisconnectReason {
- Unspecified,
- ConnectionEstablishmentFailed,
- TimedOut,
- BondingKeysMismatch,
-}
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum RemovedReason {
- RemovedByThisClient,
- ForceDisconnectedByThisClient,
- ForceDisconnectedByOtherClient,
-
- ButtonIsPrivate,
- VerifyTimeout,
- InternetBackendError,
- InvalidData,
-
- CouldntLoadDevice,
-
- DeletedByThisClient,
- DeletedByOtherClient,
- ButtonBelongsToOtherPartner,
- DeletedFromButton,
-}
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum ClickType {
- ButtonDown,
- ButtonUp,
- ButtonClick,
- ButtonSingleClick,
- ButtonDoubleClick,
- ButtonHold,
-}
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum BdAddrType {
- PublicBdAddrType,
- RandomBdAddrType,
-}
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum LatencyMode {
- NormalLatency,
- LowLatency,
- HighLatency,
-}
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum ScanWizardResult {
- WizardSuccess,
- WizardCancelledByUser,
- WizardFailedTimeout,
- WizardButtonIsPrivate,
- WizardBluetoothUnavailable,
- WizardInternetBackendError,
- WizardInvalidData,
- WizardButtonBelongsToOtherPartner,
- WizardButtonAlreadyConnectedToOtherDevice,
-}
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
-pub enum BluetoothControllerState {
- Detached,
- Resetting,
- Attached,
-}
+
+#![allow(dead_code)]
+
+use num_enum::TryFromPrimitive;
+use num_enum::IntoPrimitive;
+
+// Enums
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum CreateConnectionChannelError {
+ NoError,
+ MaxPendingConnectionsReached,
+}
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum ConnectionStatus {
+ Disconnected,
+ Connected,
+ Ready,
+}
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum DisconnectReason {
+ Unspecified,
+ ConnectionEstablishmentFailed,
+ TimedOut,
+ BondingKeysMismatch,
+}
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum RemovedReason {
+ RemovedByThisClient,
+ ForceDisconnectedByThisClient,
+ ForceDisconnectedByOtherClient,
+
+ ButtonIsPrivate,
+ VerifyTimeout,
+ InternetBackendError,
+ InvalidData,
+
+ CouldntLoadDevice,
+
+ DeletedByThisClient,
+ DeletedByOtherClient,
+ ButtonBelongsToOtherPartner,
+ DeletedFromButton,
+}
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum ClickType {
+ ButtonDown,
+ ButtonUp,
+ ButtonClick,
+ ButtonSingleClick,
+ ButtonDoubleClick,
+ ButtonHold,
+}
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum BdAddrType {
+ PublicBdAddrType,
+ RandomBdAddrType,
+}
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum LatencyMode {
+ NormalLatency,
+ LowLatency,
+ HighLatency,
+}
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum ScanWizardResult {
+ WizardSuccess,
+ WizardCancelledByUser,
+ WizardFailedTimeout,
+ WizardButtonIsPrivate,
+ WizardBluetoothUnavailable,
+ WizardInternetBackendError,
+ WizardInvalidData,
+ WizardButtonBelongsToOtherPartner,
+ WizardButtonAlreadyConnectedToOtherDevice,
+}
+
+#[repr(u8)]
+#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
+pub enum BluetoothControllerState {
+ Detached,
+ Resetting,
+ Attached,
+}
diff --git a/src/events/mod.rs b/src/events/mod.rs
index 0cfd910..0cfd910 100644..100755
--- a/src/events/mod.rs
+++ b/src/events/mod.rs
diff --git a/src/events/stream_mapper.rs b/src/events/stream_mapper.rs
index 5244d58..5244d58 100644..100755
--- a/src/events/stream_mapper.rs
+++ b/src/events/stream_mapper.rs
diff --git a/src/lib.rs b/src/lib.rs
index ba9a5f6..43f8ede 100644..100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -6,4 +6,5 @@ mod client;
pub use client::*;
pub use commands::Command;
-pub use events::Event; \ No newline at end of file
+pub use events::Event;
+pub use enums::*; \ No newline at end of file