Loading system/blueberry/facade/topshim/facade.proto +24 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,13 @@ service HfpService { rpc FetchEvents(FetchEventsRequest) returns (stream FetchEventsResponse) {} } service HfClientService { rpc StartSlc(StartSlcRequest) returns (StartSlcResponse) {} rpc StopSlc(StopSlcRequest) returns (StopSlcResponse) {} rpc ConnectAudio(ConnectAudioRequest) returns (ConnectAudioResponse) {} rpc DisconnectAudio(DisconnectAudioRequest) returns (DisconnectAudioResponse) {} } enum EventType { ADAPTER_STATE = 0; SSP_REQUEST = 1; Loading @@ -119,6 +126,7 @@ enum EventType { HFP_CONNECTION_STATE = 4; ADAPTER_PROPERTY = 5; } message FetchEventsRequest {} message FetchEventsResponse { Loading Loading @@ -171,20 +179,36 @@ message StartSlcRequest { Connection connection = 1; } message StartSlcResponse { int32 status = 1; } message StopSlcRequest { Connection connection = 1; } message StopSlcResponse { int32 status = 1; } message ConnectAudioRequest { Connection connection = 1; bool is_sco_offload_enabled = 2; bool force_cvsd = 3; } message ConnectAudioResponse { int32 status = 1; } message DisconnectAudioRequest { Connection connection = 1; } message DisconnectAudioResponse { int32 status = 1; } message SetVolumeRequest { Connection connection = 1; int32 volume = 2; Loading system/gd/rust/topshim/facade/src/hf_client_service.rs 0 → 100644 +143 −0 Original line number Diff line number Diff line //! HF Client service facade use bt_topshim::btif::{BluetoothInterface, RawAddress, ToggleableProfile}; use bt_topshim::profiles::hf_client::{BthfClientCallbacksDispatcher, HfClient}; use bt_topshim_facade_protobuf::facade::{ ConnectAudioRequest, ConnectAudioResponse, DisconnectAudioRequest, DisconnectAudioResponse, StartSlcRequest, StartSlcResponse, StopSlcRequest, StopSlcResponse, }; use bt_topshim_facade_protobuf::facade_grpc::{create_hf_client_service, HfClientService}; use grpcio::*; use num_traits::cast::ToPrimitive; use std::str::from_utf8; use std::sync::{Arc, Mutex}; use tokio::runtime::Runtime; fn get_hf_client_dispatcher() -> BthfClientCallbacksDispatcher { BthfClientCallbacksDispatcher { dispatch: Box::new(move |_cb| {}) } } /// Main object for Hf(Hands free) client facade service #[derive(Clone)] pub struct HfClientServiceImpl { #[allow(dead_code)] rt: Arc<Runtime>, pub hf_client: Arc<Mutex<HfClient>>, } impl HfClientServiceImpl { /// Create a new instance of the root facade service pub fn create(rt: Arc<Runtime>, btif_intf: Arc<Mutex<BluetoothInterface>>) -> grpcio::Service { let hf_client = Arc::new(Mutex::new(HfClient::new(&btif_intf.lock().unwrap()))); hf_client.lock().unwrap().initialize(get_hf_client_dispatcher()); hf_client.lock().unwrap().enable(); create_hf_client_service(Self { rt, hf_client }) } } impl HfClientService for HfClientServiceImpl { fn start_slc( &mut self, ctx: RpcContext<'_>, req: StartSlcRequest, sink: UnarySink<StartSlcResponse>, ) { let hf_client = self.hf_client.clone(); ctx.spawn(async move { let addr_bytes = &req.connection.unwrap().cookie; let bt_addr = from_utf8(addr_bytes).unwrap(); if let Some(addr) = RawAddress::from_string(bt_addr) { let status = hf_client.lock().unwrap().connect(addr); let mut resp = StartSlcResponse::new(); resp.status = status.to_i32().unwrap(); sink.success(resp).await.unwrap(); } else { sink.fail(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, format!("Invalid Request Address: {}", bt_addr), )) .await .unwrap(); } }) } fn stop_slc( &mut self, ctx: RpcContext<'_>, req: StopSlcRequest, sink: UnarySink<StopSlcResponse>, ) { let hf_client = self.hf_client.clone(); ctx.spawn(async move { let addr_bytes = &req.connection.unwrap().cookie; let bt_addr = from_utf8(addr_bytes).unwrap(); if let Some(addr) = RawAddress::from_string(bt_addr) { let status = hf_client.lock().unwrap().disconnect(addr); let mut resp = StopSlcResponse::new(); resp.status = status.to_i32().unwrap(); sink.success(resp).await.unwrap(); } else { sink.fail(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, format!("Invalid Request Address: {}", bt_addr), )) .await .unwrap(); } }) } fn connect_audio( &mut self, ctx: RpcContext<'_>, req: ConnectAudioRequest, sink: UnarySink<ConnectAudioResponse>, ) { let hf_client = self.hf_client.clone(); ctx.spawn(async move { let addr_bytes = &req.connection.unwrap().cookie; let bt_addr = from_utf8(addr_bytes).unwrap(); if let Some(addr) = RawAddress::from_string(bt_addr) { let status = hf_client.lock().unwrap().connect_audio(addr); let mut resp = ConnectAudioResponse::new(); resp.status = status.to_i32().unwrap(); sink.success(resp).await.unwrap(); } else { sink.fail(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, format!("Invalid Request Address: {}", bt_addr), )) .await .unwrap(); } }) } fn disconnect_audio( &mut self, ctx: RpcContext<'_>, req: DisconnectAudioRequest, sink: UnarySink<DisconnectAudioResponse>, ) { let hf_client = self.hf_client.clone(); ctx.spawn(async move { let addr_bytes = &req.connection.unwrap().cookie; let bt_addr = from_utf8(addr_bytes).unwrap(); if let Some(addr) = RawAddress::from_string(bt_addr) { let status = hf_client.lock().unwrap().disconnect_audio(addr); let mut resp = DisconnectAudioResponse::new(); resp.status = status.to_i32().unwrap(); sink.success(resp).await.unwrap(); } else { sink.fail(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, format!("Invalid Request Address: {}", bt_addr), )) .await .unwrap(); } }) } } system/gd/rust/topshim/facade/src/main.rs +5 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ use tokio::runtime::Runtime; mod adapter_service; mod gatt_service; mod hf_client_service; mod hfp_service; mod media_service; mod security_service; Loading Loading @@ -86,6 +87,9 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) { let gatt_service_impl = gatt_service::GattServiceImpl::create(rt.clone(), btif_intf.clone()); let hf_client_service_impl = hf_client_service::HfClientServiceImpl::create(rt.clone(), btif_intf.clone()); let hfp_service_impl = hfp_service::HfpServiceImpl::create(rt.clone(), btif_intf.clone()); let media_service_impl = media_service::MediaServiceImpl::create(rt.clone(), btif_intf.clone()); Loading @@ -100,6 +104,7 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) { .register_service(adapter_service_impl) .register_service(security_service_impl) .register_service(gatt_service_impl) .register_service(hf_client_service_impl) .register_service(hfp_service_impl) .register_service(media_service_impl) .bind("0.0.0.0", grpc_port) Loading Loading
system/blueberry/facade/topshim/facade.proto +24 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,13 @@ service HfpService { rpc FetchEvents(FetchEventsRequest) returns (stream FetchEventsResponse) {} } service HfClientService { rpc StartSlc(StartSlcRequest) returns (StartSlcResponse) {} rpc StopSlc(StopSlcRequest) returns (StopSlcResponse) {} rpc ConnectAudio(ConnectAudioRequest) returns (ConnectAudioResponse) {} rpc DisconnectAudio(DisconnectAudioRequest) returns (DisconnectAudioResponse) {} } enum EventType { ADAPTER_STATE = 0; SSP_REQUEST = 1; Loading @@ -119,6 +126,7 @@ enum EventType { HFP_CONNECTION_STATE = 4; ADAPTER_PROPERTY = 5; } message FetchEventsRequest {} message FetchEventsResponse { Loading Loading @@ -171,20 +179,36 @@ message StartSlcRequest { Connection connection = 1; } message StartSlcResponse { int32 status = 1; } message StopSlcRequest { Connection connection = 1; } message StopSlcResponse { int32 status = 1; } message ConnectAudioRequest { Connection connection = 1; bool is_sco_offload_enabled = 2; bool force_cvsd = 3; } message ConnectAudioResponse { int32 status = 1; } message DisconnectAudioRequest { Connection connection = 1; } message DisconnectAudioResponse { int32 status = 1; } message SetVolumeRequest { Connection connection = 1; int32 volume = 2; Loading
system/gd/rust/topshim/facade/src/hf_client_service.rs 0 → 100644 +143 −0 Original line number Diff line number Diff line //! HF Client service facade use bt_topshim::btif::{BluetoothInterface, RawAddress, ToggleableProfile}; use bt_topshim::profiles::hf_client::{BthfClientCallbacksDispatcher, HfClient}; use bt_topshim_facade_protobuf::facade::{ ConnectAudioRequest, ConnectAudioResponse, DisconnectAudioRequest, DisconnectAudioResponse, StartSlcRequest, StartSlcResponse, StopSlcRequest, StopSlcResponse, }; use bt_topshim_facade_protobuf::facade_grpc::{create_hf_client_service, HfClientService}; use grpcio::*; use num_traits::cast::ToPrimitive; use std::str::from_utf8; use std::sync::{Arc, Mutex}; use tokio::runtime::Runtime; fn get_hf_client_dispatcher() -> BthfClientCallbacksDispatcher { BthfClientCallbacksDispatcher { dispatch: Box::new(move |_cb| {}) } } /// Main object for Hf(Hands free) client facade service #[derive(Clone)] pub struct HfClientServiceImpl { #[allow(dead_code)] rt: Arc<Runtime>, pub hf_client: Arc<Mutex<HfClient>>, } impl HfClientServiceImpl { /// Create a new instance of the root facade service pub fn create(rt: Arc<Runtime>, btif_intf: Arc<Mutex<BluetoothInterface>>) -> grpcio::Service { let hf_client = Arc::new(Mutex::new(HfClient::new(&btif_intf.lock().unwrap()))); hf_client.lock().unwrap().initialize(get_hf_client_dispatcher()); hf_client.lock().unwrap().enable(); create_hf_client_service(Self { rt, hf_client }) } } impl HfClientService for HfClientServiceImpl { fn start_slc( &mut self, ctx: RpcContext<'_>, req: StartSlcRequest, sink: UnarySink<StartSlcResponse>, ) { let hf_client = self.hf_client.clone(); ctx.spawn(async move { let addr_bytes = &req.connection.unwrap().cookie; let bt_addr = from_utf8(addr_bytes).unwrap(); if let Some(addr) = RawAddress::from_string(bt_addr) { let status = hf_client.lock().unwrap().connect(addr); let mut resp = StartSlcResponse::new(); resp.status = status.to_i32().unwrap(); sink.success(resp).await.unwrap(); } else { sink.fail(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, format!("Invalid Request Address: {}", bt_addr), )) .await .unwrap(); } }) } fn stop_slc( &mut self, ctx: RpcContext<'_>, req: StopSlcRequest, sink: UnarySink<StopSlcResponse>, ) { let hf_client = self.hf_client.clone(); ctx.spawn(async move { let addr_bytes = &req.connection.unwrap().cookie; let bt_addr = from_utf8(addr_bytes).unwrap(); if let Some(addr) = RawAddress::from_string(bt_addr) { let status = hf_client.lock().unwrap().disconnect(addr); let mut resp = StopSlcResponse::new(); resp.status = status.to_i32().unwrap(); sink.success(resp).await.unwrap(); } else { sink.fail(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, format!("Invalid Request Address: {}", bt_addr), )) .await .unwrap(); } }) } fn connect_audio( &mut self, ctx: RpcContext<'_>, req: ConnectAudioRequest, sink: UnarySink<ConnectAudioResponse>, ) { let hf_client = self.hf_client.clone(); ctx.spawn(async move { let addr_bytes = &req.connection.unwrap().cookie; let bt_addr = from_utf8(addr_bytes).unwrap(); if let Some(addr) = RawAddress::from_string(bt_addr) { let status = hf_client.lock().unwrap().connect_audio(addr); let mut resp = ConnectAudioResponse::new(); resp.status = status.to_i32().unwrap(); sink.success(resp).await.unwrap(); } else { sink.fail(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, format!("Invalid Request Address: {}", bt_addr), )) .await .unwrap(); } }) } fn disconnect_audio( &mut self, ctx: RpcContext<'_>, req: DisconnectAudioRequest, sink: UnarySink<DisconnectAudioResponse>, ) { let hf_client = self.hf_client.clone(); ctx.spawn(async move { let addr_bytes = &req.connection.unwrap().cookie; let bt_addr = from_utf8(addr_bytes).unwrap(); if let Some(addr) = RawAddress::from_string(bt_addr) { let status = hf_client.lock().unwrap().disconnect_audio(addr); let mut resp = DisconnectAudioResponse::new(); resp.status = status.to_i32().unwrap(); sink.success(resp).await.unwrap(); } else { sink.fail(RpcStatus::with_message( RpcStatusCode::INVALID_ARGUMENT, format!("Invalid Request Address: {}", bt_addr), )) .await .unwrap(); } }) } }
system/gd/rust/topshim/facade/src/main.rs +5 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ use tokio::runtime::Runtime; mod adapter_service; mod gatt_service; mod hf_client_service; mod hfp_service; mod media_service; mod security_service; Loading Loading @@ -86,6 +87,9 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) { let gatt_service_impl = gatt_service::GattServiceImpl::create(rt.clone(), btif_intf.clone()); let hf_client_service_impl = hf_client_service::HfClientServiceImpl::create(rt.clone(), btif_intf.clone()); let hfp_service_impl = hfp_service::HfpServiceImpl::create(rt.clone(), btif_intf.clone()); let media_service_impl = media_service::MediaServiceImpl::create(rt.clone(), btif_intf.clone()); Loading @@ -100,6 +104,7 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) { .register_service(adapter_service_impl) .register_service(security_service_impl) .register_service(gatt_service_impl) .register_service(hf_client_service_impl) .register_service(hfp_service_impl) .register_service(media_service_impl) .bind("0.0.0.0", grpc_port) Loading