blob: 05bfa4673db461f1148f42403aff5afb75667a1e [file] [log] [blame]
// Copyright 2019 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 {
crate::config::{BoardInfo, DeviceInfo, ProductInfo},
anyhow::{Context as _, Error},
fidl_fuchsia_hwinfo::{
BoardRequest, BoardRequestStream, DeviceRequest, DeviceRequestStream, ProductRequest,
ProductRequestStream,
},
fuchsia_async as fasync,
futures::prelude::*,
std::sync::{Arc, RwLock},
};
type DeviceInfoTable = Arc<RwLock<DeviceInfo>>;
type BoardInfoTable = Arc<RwLock<BoardInfo>>;
type ProductInfoTable = Arc<RwLock<ProductInfo>>;
pub struct DeviceInfoServer {
device_info_table: DeviceInfoTable,
}
impl DeviceInfoServer {
pub fn new(device_info_table: DeviceInfoTable) -> Self {
Self { device_info_table }
}
pub async fn handle_requests_from_stream(
&self,
mut stream: DeviceRequestStream,
) -> Result<(), Error> {
while let Some(req) = stream.try_next().await? {
self.handle_request(req).await?;
}
Ok(())
}
async fn handle_request(&self, request: DeviceRequest) -> Result<(), Error> {
match request {
DeviceRequest::GetInfo { responder } => {
responder
.send(&self.device_info_table.read().unwrap().clone().into())
.context("error sending response")?;
}
};
Ok(())
}
}
pub struct BoardInfoServer {
board_info_table: BoardInfoTable,
}
impl BoardInfoServer {
pub fn new(board_info_table: BoardInfoTable) -> Self {
Self { board_info_table }
}
pub async fn handle_requests_from_stream(
&self,
mut stream: BoardRequestStream,
) -> Result<(), Error> {
while let Some(req) = stream.try_next().await? {
self.handle_request(req).await?;
}
Ok(())
}
async fn handle_request(&self, request: BoardRequest) -> Result<(), Error> {
match request {
BoardRequest::GetInfo { responder } => {
responder
.send(&self.board_info_table.read().unwrap().clone().into())
.context("error sending response")?;
}
};
Ok(())
}
}
pub struct ProductInfoServer {
product_info_table: ProductInfoTable,
}
impl ProductInfoServer {
pub fn new(product_info_table: ProductInfoTable) -> Self {
Self { product_info_table }
}
pub async fn handle_requests_from_stream(
&self,
mut stream: ProductRequestStream,
) -> Result<(), Error> {
while let Some(req) = stream.try_next().await? {
self.handle_request(req).await?;
}
Ok(())
}
async fn handle_request(&self, request: ProductRequest) -> Result<(), Error> {
match request {
ProductRequest::GetInfo { responder } => {
responder
.send(&self.product_info_table.read().unwrap().clone().into())
.context("error sending response")?;
}
};
Ok(())
}
}
pub fn spawn_device_info_server(server: DeviceInfoServer, stream: DeviceRequestStream) {
fasync::Task::spawn(async move {
server
.handle_requests_from_stream(stream)
.await
.unwrap_or_else(|e| tracing::error!("Failed to run device_info service: {:?}", e));
})
.detach();
}
pub fn spawn_board_info_server(server: BoardInfoServer, stream: BoardRequestStream) {
fasync::Task::spawn(async move {
server
.handle_requests_from_stream(stream)
.await
.unwrap_or_else(|e| tracing::error!("Failed to run board_info service: {:?}", e));
})
.detach();
}
pub fn spawn_product_info_server(server: ProductInfoServer, stream: ProductRequestStream) {
fasync::Task::spawn(async move {
server
.handle_requests_from_stream(stream)
.await
.unwrap_or_else(|e| tracing::error!("Failed to run product_info service: {:?}", e));
})
.detach();
}