speedtest/
server.rs

1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::socket;
6use flex_client::fidl::{ControlHandle as _, Responder as _};
7use log::{error, warn};
8use {flex_fuchsia_developer_ffx_speedtest as fspeedtest, fuchsia_async as fasync};
9
10pub struct Server {
11    scope: fasync::Scope,
12}
13
14impl Default for Server {
15    fn default() -> Self {
16        Self::new(fasync::Scope::new_with_name("speedtest-server"))
17    }
18}
19
20impl Server {
21    pub fn new(scope: fasync::Scope) -> Self {
22        Self { scope }
23    }
24
25    pub fn handle_request(&self, req: fspeedtest::SpeedtestRequest) -> Result<(), fidl::Error> {
26        match req {
27            fspeedtest::SpeedtestRequest::Ping { responder } => responder.send()?,
28            fspeedtest::SpeedtestRequest::SocketDown { socket, params, responder } => {
29                match params.try_into() {
30                    Ok(params) => {
31                        let _: fasync::JoinHandle<()> = self.scope.spawn(async move {
32                            let report = socket::Transfer { socket, params }.receive().await;
33                            match report {
34                                Ok(report) => responder.send(&report.into()).unwrap_or_else(|e| {
35                                    if !e.is_closed() {
36                                        error!("error responding to transfer {e:?}")
37                                    }
38                                }),
39                                Err(e) => {
40                                    error!("SocketDown failed with {e:?}");
41                                    responder
42                                        .control_handle()
43                                        .shutdown_with_epitaph(zx_status::Status::INTERNAL);
44                                }
45                            }
46                        });
47                    }
48                    Err(e) => {
49                        error!("error initiating transfer: {e:?}");
50                        responder
51                            .control_handle()
52                            .shutdown_with_epitaph(zx_status::Status::INVALID_ARGS);
53                    }
54                }
55            }
56            fspeedtest::SpeedtestRequest::SocketUp { socket, params, responder } => {
57                match params.try_into() {
58                    Ok(params) => {
59                        let _: fasync::JoinHandle<()> = self.scope.spawn(async move {
60                            let report = socket::Transfer { socket, params }.send().await;
61                            match report {
62                                Ok(report) => responder.send(&report.into()).unwrap_or_else(|e| {
63                                    if !e.is_closed() {
64                                        error!("error responding to transfer {e:?}")
65                                    }
66                                }),
67                                Err(e) => {
68                                    error!("SocketUp failed with {e:?}");
69                                    responder
70                                        .control_handle()
71                                        .shutdown_with_epitaph(zx_status::Status::INTERNAL)
72                                }
73                            }
74                        });
75                    }
76                    Err(e) => {
77                        error!("error initiating transfer: {e:?}");
78                        responder
79                            .control_handle()
80                            .shutdown_with_epitaph(zx_status::Status::INVALID_ARGS);
81                    }
82                }
83            }
84            fspeedtest::SpeedtestRequest::_UnknownMethod { ordinal, .. } => {
85                warn!("ignoring unknown method {ordinal}");
86            }
87        }
88        Ok(())
89    }
90}