Loading system/gd/rust/linux/client/src/command_handler.rs +71 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ use crate::callbacks::{BtGattCallback, BtGattServerCallback}; use crate::ClientContext; use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::{BtConnectionState, BtStatus, BtTransport}; use bt_topshim::profiles::hid_host::BthhReportType; use bt_topshim::profiles::{gatt::LePhy, ProfileConnectionState}; use btstack::bluetooth::{BluetoothDevice, IBluetooth, IBluetoothQA}; use btstack::bluetooth_gatt::{GattWriteType, IBluetoothGatt, ScanSettings, ScanType}; Loading Loading @@ -213,6 +214,18 @@ fn build_commands() -> HashMap<String, CommandOption> { function_pointer: CommandHandler::cmd_socket, }, ); command_options.insert( String::from("hid"), CommandOption { rules: vec![ String::from("hid get-report <address> <Input|Output|Feature> <report_id>"), String::from("hid set-report <address> <Input|Output|Feature> <report_value>"), String::from("hid send-data <address> <data>"), ], description: String::from("Socket manager utilities."), function_pointer: CommandHandler::cmd_hid, }, ); command_options.insert( String::from("get-address"), CommandOption { Loading Loading @@ -1390,6 +1403,64 @@ impl CommandHandler { Ok(()) } fn cmd_hid(&mut self, args: &Vec<String>) -> CommandResult { if !self.context.lock().unwrap().adapter_ready { return Err(self.adapter_not_ready()); } let command = get_arg(args, 0)?; match &command[..] { "get-report" => { let addr = String::from(get_arg(args, 1)?); let report_type = match &get_arg(args, 2)?[..] { "Input" => BthhReportType::InputReport, "Output" => BthhReportType::OutputReport, "Feature" => BthhReportType::FeatureReport, _ => { return Err("Failed to parse report type".into()); } }; let report_id = String::from(get_arg(args, 3)?) .parse::<u8>() .or(Err("Failed parsing report_id"))?; self.context.lock().unwrap().qa_dbus.as_mut().unwrap().get_hid_report( addr, report_type, report_id, ); } "set-report" => { let addr = String::from(get_arg(args, 1)?); let report_type = match &get_arg(args, 2)?[..] { "Input" => BthhReportType::InputReport, "Output" => BthhReportType::OutputReport, "Feature" => BthhReportType::FeatureReport, _ => { return Err("Failed to parse report type".into()); } }; let report_value = String::from(get_arg(args, 3)?); self.context.lock().unwrap().qa_dbus.as_mut().unwrap().set_hid_report( addr, report_type, report_value, ); } "send-data" => { let addr = String::from(get_arg(args, 1)?); let data = String::from(get_arg(args, 2)?); self.context.lock().unwrap().qa_dbus.as_mut().unwrap().send_hid_data(addr, data); } _ => return Err(CommandError::InvalidArgs), }; Ok(()) } /// Get the list of rules of supported commands pub fn get_command_rule_list(&self) -> Vec<String> { self.command_options.values().flat_map(|cmd| cmd.rules.clone()).collect() Loading system/gd/rust/linux/client/src/dbus_iface.rs +25 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ use bt_topshim::btif::{ BtTransport, Uuid, Uuid128Bit, }; use bt_topshim::profiles::gatt::{AdvertisingStatus, GattStatus, LePhy}; use bt_topshim::profiles::hid_host::BthhReportType; use bt_topshim::profiles::socket::SocketType; use bt_topshim::profiles::ProfileConnectionState; Loading Loading @@ -75,6 +76,7 @@ impl_dbus_arg_enum!(SocketType); impl_dbus_arg_enum!(SuspendMode); impl_dbus_arg_enum!(SuspendType); impl_dbus_arg_from_into!(Uuid, Vec<u8>); impl_dbus_arg_enum!(BthhReportType); impl RefArgToRust for Uuid { type RustType = Vec<u8>; Loading Loading @@ -635,6 +637,29 @@ impl IBluetoothQA for BluetoothQADBus { fn set_connectable(&mut self, mode: bool) -> bool { dbus_generated!() } #[dbus_method("GetHIDReport")] fn get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus { dbus_generated!() } #[dbus_method("SetHIDReport")] fn set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus { dbus_generated!() } #[dbus_method("SendHIDData")] fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus; } #[dbus_propmap(AdapterWithEnabled)] Loading system/gd/rust/linux/service/src/iface_bluetooth.rs +29 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,8 @@ use bt_topshim::btif::{ use bt_topshim::profiles::socket::SocketType; use bt_topshim::profiles::ProfileConnectionState; use bt_topshim::profiles::hid_host::BthhReportType; use btstack::bluetooth::{ Bluetooth, BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, IBluetoothQA, Loading Loading @@ -591,6 +593,8 @@ impl ISuspendCallback for SuspendCallbackDBus { } } impl_dbus_arg_enum!(BthhReportType); #[allow(dead_code)] struct IBluetoothQADBus {} Loading @@ -610,4 +614,29 @@ impl IBluetoothQA for IBluetoothQADBus { fn set_connectable(&mut self, mode: bool) -> bool { dbus_generated!() } #[dbus_method("GetHIDReport")] fn get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus { dbus_generated!() } #[dbus_method("SetHIDReport")] fn set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus { dbus_generated!() } #[dbus_method("SendHIDData")] fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus { dbus_generated!() } } system/gd/rust/linux/stack/src/bluetooth.rs +57 −2 Original line number Diff line number Diff line Loading @@ -10,8 +10,8 @@ use bt_topshim::btif::{ use bt_topshim::{ metrics, profiles::hid_host::{ BthhConnectionState, BthhHidInfo, BthhProtocolMode, BthhStatus, HHCallbacks, HHCallbacksDispatcher, HidHost, BthhConnectionState, BthhHidInfo, BthhProtocolMode, BthhReportType, BthhStatus, HHCallbacks, HHCallbacksDispatcher, HidHost, }, profiles::sdp::{BtSdpRecord, Sdp, SdpCallbacks, SdpCallbacksDispatcher}, profiles::ProfileConnectionState, Loading Loading @@ -206,6 +206,25 @@ pub trait IBluetoothQA { /// Sets connectability. Returns true on success, false otherwise. fn set_connectable(&mut self, mode: bool) -> bool; /// Gets HID report on the peer. fn get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus; /// Sets HID report to the peer. fn set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus; /// Snd HID data report to the peer. fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus; } /// Delayed actions from adapter events. Loading Loading @@ -2050,4 +2069,40 @@ impl IBluetoothQA for Bluetooth { if mode { BtScanMode::Connectable } else { BtScanMode::None_ }, )) == 0 } fn get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus { if let Some(mut addr) = RawAddress::from_string(addr) { self.hh.as_mut().unwrap().get_report(&mut addr, report_type, report_id, 128) } else { BtStatus::InvalidParam } } fn set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus { if let Some(mut addr) = RawAddress::from_string(addr) { let mut rb = report.clone().into_bytes(); self.hh.as_mut().unwrap().set_report(&mut addr, report_type, rb.as_mut_slice()) } else { BtStatus::InvalidParam } } fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus { if let Some(mut addr) = RawAddress::from_string(addr) { let mut rb = data.clone().into_bytes(); self.hh.as_mut().unwrap().send_data(&mut addr, rb.as_mut_slice()) } else { BtStatus::InvalidParam } } } system/gd/rust/topshim/src/profiles/hid_host.rs +12 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,18 @@ impl HidHost { )) } #[profile_enabled_or(BtStatus::NotReady)] pub fn send_data(&mut self, addr: &mut RawAddress, data: &mut [u8]) -> BtStatus { let addr_ptr = LTCheckedPtrMut::from_ref(addr); let data_ptr = LTCheckedPtrMut::from(data); BtStatus::from(ccall!( self, send_data, addr_ptr.into(), data_ptr.cast_into::<std::os::raw::c_char>() )) } #[profile_enabled_or] pub fn cleanup(&mut self) { ccall!(self, cleanup) Loading Loading
system/gd/rust/linux/client/src/command_handler.rs +71 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ use crate::callbacks::{BtGattCallback, BtGattServerCallback}; use crate::ClientContext; use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::{BtConnectionState, BtStatus, BtTransport}; use bt_topshim::profiles::hid_host::BthhReportType; use bt_topshim::profiles::{gatt::LePhy, ProfileConnectionState}; use btstack::bluetooth::{BluetoothDevice, IBluetooth, IBluetoothQA}; use btstack::bluetooth_gatt::{GattWriteType, IBluetoothGatt, ScanSettings, ScanType}; Loading Loading @@ -213,6 +214,18 @@ fn build_commands() -> HashMap<String, CommandOption> { function_pointer: CommandHandler::cmd_socket, }, ); command_options.insert( String::from("hid"), CommandOption { rules: vec![ String::from("hid get-report <address> <Input|Output|Feature> <report_id>"), String::from("hid set-report <address> <Input|Output|Feature> <report_value>"), String::from("hid send-data <address> <data>"), ], description: String::from("Socket manager utilities."), function_pointer: CommandHandler::cmd_hid, }, ); command_options.insert( String::from("get-address"), CommandOption { Loading Loading @@ -1390,6 +1403,64 @@ impl CommandHandler { Ok(()) } fn cmd_hid(&mut self, args: &Vec<String>) -> CommandResult { if !self.context.lock().unwrap().adapter_ready { return Err(self.adapter_not_ready()); } let command = get_arg(args, 0)?; match &command[..] { "get-report" => { let addr = String::from(get_arg(args, 1)?); let report_type = match &get_arg(args, 2)?[..] { "Input" => BthhReportType::InputReport, "Output" => BthhReportType::OutputReport, "Feature" => BthhReportType::FeatureReport, _ => { return Err("Failed to parse report type".into()); } }; let report_id = String::from(get_arg(args, 3)?) .parse::<u8>() .or(Err("Failed parsing report_id"))?; self.context.lock().unwrap().qa_dbus.as_mut().unwrap().get_hid_report( addr, report_type, report_id, ); } "set-report" => { let addr = String::from(get_arg(args, 1)?); let report_type = match &get_arg(args, 2)?[..] { "Input" => BthhReportType::InputReport, "Output" => BthhReportType::OutputReport, "Feature" => BthhReportType::FeatureReport, _ => { return Err("Failed to parse report type".into()); } }; let report_value = String::from(get_arg(args, 3)?); self.context.lock().unwrap().qa_dbus.as_mut().unwrap().set_hid_report( addr, report_type, report_value, ); } "send-data" => { let addr = String::from(get_arg(args, 1)?); let data = String::from(get_arg(args, 2)?); self.context.lock().unwrap().qa_dbus.as_mut().unwrap().send_hid_data(addr, data); } _ => return Err(CommandError::InvalidArgs), }; Ok(()) } /// Get the list of rules of supported commands pub fn get_command_rule_list(&self) -> Vec<String> { self.command_options.values().flat_map(|cmd| cmd.rules.clone()).collect() Loading
system/gd/rust/linux/client/src/dbus_iface.rs +25 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ use bt_topshim::btif::{ BtTransport, Uuid, Uuid128Bit, }; use bt_topshim::profiles::gatt::{AdvertisingStatus, GattStatus, LePhy}; use bt_topshim::profiles::hid_host::BthhReportType; use bt_topshim::profiles::socket::SocketType; use bt_topshim::profiles::ProfileConnectionState; Loading Loading @@ -75,6 +76,7 @@ impl_dbus_arg_enum!(SocketType); impl_dbus_arg_enum!(SuspendMode); impl_dbus_arg_enum!(SuspendType); impl_dbus_arg_from_into!(Uuid, Vec<u8>); impl_dbus_arg_enum!(BthhReportType); impl RefArgToRust for Uuid { type RustType = Vec<u8>; Loading Loading @@ -635,6 +637,29 @@ impl IBluetoothQA for BluetoothQADBus { fn set_connectable(&mut self, mode: bool) -> bool { dbus_generated!() } #[dbus_method("GetHIDReport")] fn get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus { dbus_generated!() } #[dbus_method("SetHIDReport")] fn set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus { dbus_generated!() } #[dbus_method("SendHIDData")] fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus; } #[dbus_propmap(AdapterWithEnabled)] Loading
system/gd/rust/linux/service/src/iface_bluetooth.rs +29 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,8 @@ use bt_topshim::btif::{ use bt_topshim::profiles::socket::SocketType; use bt_topshim::profiles::ProfileConnectionState; use bt_topshim::profiles::hid_host::BthhReportType; use btstack::bluetooth::{ Bluetooth, BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, IBluetoothQA, Loading Loading @@ -591,6 +593,8 @@ impl ISuspendCallback for SuspendCallbackDBus { } } impl_dbus_arg_enum!(BthhReportType); #[allow(dead_code)] struct IBluetoothQADBus {} Loading @@ -610,4 +614,29 @@ impl IBluetoothQA for IBluetoothQADBus { fn set_connectable(&mut self, mode: bool) -> bool { dbus_generated!() } #[dbus_method("GetHIDReport")] fn get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus { dbus_generated!() } #[dbus_method("SetHIDReport")] fn set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus { dbus_generated!() } #[dbus_method("SendHIDData")] fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus { dbus_generated!() } }
system/gd/rust/linux/stack/src/bluetooth.rs +57 −2 Original line number Diff line number Diff line Loading @@ -10,8 +10,8 @@ use bt_topshim::btif::{ use bt_topshim::{ metrics, profiles::hid_host::{ BthhConnectionState, BthhHidInfo, BthhProtocolMode, BthhStatus, HHCallbacks, HHCallbacksDispatcher, HidHost, BthhConnectionState, BthhHidInfo, BthhProtocolMode, BthhReportType, BthhStatus, HHCallbacks, HHCallbacksDispatcher, HidHost, }, profiles::sdp::{BtSdpRecord, Sdp, SdpCallbacks, SdpCallbacksDispatcher}, profiles::ProfileConnectionState, Loading Loading @@ -206,6 +206,25 @@ pub trait IBluetoothQA { /// Sets connectability. Returns true on success, false otherwise. fn set_connectable(&mut self, mode: bool) -> bool; /// Gets HID report on the peer. fn get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus; /// Sets HID report to the peer. fn set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus; /// Snd HID data report to the peer. fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus; } /// Delayed actions from adapter events. Loading Loading @@ -2050,4 +2069,40 @@ impl IBluetoothQA for Bluetooth { if mode { BtScanMode::Connectable } else { BtScanMode::None_ }, )) == 0 } fn get_hid_report( &mut self, addr: String, report_type: BthhReportType, report_id: u8, ) -> BtStatus { if let Some(mut addr) = RawAddress::from_string(addr) { self.hh.as_mut().unwrap().get_report(&mut addr, report_type, report_id, 128) } else { BtStatus::InvalidParam } } fn set_hid_report( &mut self, addr: String, report_type: BthhReportType, report: String, ) -> BtStatus { if let Some(mut addr) = RawAddress::from_string(addr) { let mut rb = report.clone().into_bytes(); self.hh.as_mut().unwrap().set_report(&mut addr, report_type, rb.as_mut_slice()) } else { BtStatus::InvalidParam } } fn send_hid_data(&mut self, addr: String, data: String) -> BtStatus { if let Some(mut addr) = RawAddress::from_string(addr) { let mut rb = data.clone().into_bytes(); self.hh.as_mut().unwrap().send_data(&mut addr, rb.as_mut_slice()) } else { BtStatus::InvalidParam } } }
system/gd/rust/topshim/src/profiles/hid_host.rs +12 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,18 @@ impl HidHost { )) } #[profile_enabled_or(BtStatus::NotReady)] pub fn send_data(&mut self, addr: &mut RawAddress, data: &mut [u8]) -> BtStatus { let addr_ptr = LTCheckedPtrMut::from_ref(addr); let data_ptr = LTCheckedPtrMut::from(data); BtStatus::from(ccall!( self, send_data, addr_ptr.into(), data_ptr.cast_into::<std::os::raw::c_char>() )) } #[profile_enabled_or] pub fn cleanup(&mut self) { ccall!(self, cleanup) Loading