| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use failure::Error; |
| use fuchsia_bluetooth::error::Error as BTError; |
| use fuchsia_syslog::macros::*; |
| use futures::channel::mpsc; |
| use futures::StreamExt; |
| use parking_lot::RwLock; |
| use serde_json::Value; |
| use std::sync::Arc; |
| |
| // Sl4f related inclusions |
| use crate::server::sl4f::Sl4f; |
| use crate::server::sl4f_types::{AsyncRequest, AsyncResponse, FacadeType}; |
| |
| // Translation layers go here (i.e netstack_method_to_fidl) |
| use crate::bluetooth::commands::ble_advertise_method_to_fidl; |
| use crate::bluetooth::commands::ble_method_to_fidl; |
| use crate::bluetooth::commands::gatt_client_method_to_fidl; |
| use crate::bluetooth::commands::gatt_server_method_to_fidl; |
| use crate::netstack::commands::netstack_method_to_fidl; |
| use crate::wlan::commands::wlan_method_to_fidl; |
| |
| pub async fn run_fidl_loop( |
| sl4f_session: Arc<RwLock<Sl4f>>, receiver: mpsc::UnboundedReceiver<AsyncRequest>, |
| ) { |
| const CONCURRENT_REQ_LIMIT: usize = 10; // TODO(CONN-6) figure out a good parallel value for this |
| |
| let session = &sl4f_session; |
| let handler = async move |request| { |
| await!(handle_request(Arc::clone(session), request)).unwrap(); |
| }; |
| |
| let receiver_fut = receiver.for_each_concurrent(CONCURRENT_REQ_LIMIT, handler); |
| |
| await!(receiver_fut); |
| } |
| |
| async fn handle_request(sl4f_session: Arc<RwLock<Sl4f>>, request: AsyncRequest) -> Result<(), Error> { |
| match request { |
| AsyncRequest { tx, id, method_type, name, params } => { |
| let curr_sl4f_session = sl4f_session.clone(); |
| fx_log_info!(tag: "run_fidl_loop", |
| "Received synchronous request: {:?}, {:?}, {:?}, {:?}, {:?}", |
| tx, id, method_type, name, params); |
| match await!(method_to_fidl(method_type, name, params, curr_sl4f_session)) { |
| Ok(response) => { |
| let async_response = AsyncResponse::new(Ok(response)); |
| |
| // Ignore any tx sending errors since there is not a recovery path. The |
| // connection to the test server may be broken. |
| let _ = tx.send(async_response); |
| }, |
| Err(e) => { |
| println!("Error returned from calling method_to_fidl {}", e); |
| let async_response = AsyncResponse::new(Err(e)); |
| |
| // Ignore any tx sending errors since there is not a recovery path. The |
| // connection to the test server may be broken. |
| let _ = tx.send(async_response); |
| } |
| }; |
| } |
| } |
| Ok(()) |
| } |
| |
| async fn method_to_fidl( |
| method_type: String, method_name: String, args: Value, sl4f_session: Arc<RwLock<Sl4f>>, |
| ) -> Result<Value, Error> { |
| match FacadeType::from_str(&method_type) { |
| FacadeType::BleAdvertiseFacade => await!(ble_advertise_method_to_fidl( |
| method_name, |
| args, |
| sl4f_session.read().get_ble_advertise_facade(), |
| )), |
| FacadeType::Bluetooth => await!(ble_method_to_fidl( |
| method_name, |
| args, |
| sl4f_session.read().get_bt_facade(), |
| )), |
| FacadeType::GattClientFacade => await!(gatt_client_method_to_fidl( |
| method_name, |
| args, |
| sl4f_session.read().get_gatt_client_facade(), |
| )), |
| FacadeType::GattServerFacade => await!(gatt_server_method_to_fidl( |
| method_name, |
| args, |
| sl4f_session.read().get_gatt_server_facade(), |
| )), |
| FacadeType::NetstackFacade => await!(netstack_method_to_fidl( |
| method_name, |
| args, |
| sl4f_session.read().get_netstack_facade(), |
| )), |
| FacadeType::Wlan => await!(wlan_method_to_fidl( |
| method_name, |
| args, |
| sl4f_session.read().get_wlan_facade() |
| )), |
| _ => Err(BTError::new("Invalid FIDL method type").into()), |
| } |
| } |