blob: 6417c51e849f8323ae7ccb1fd608b26b9d7b776f [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.
#![feature(async_await, await_macro)]
use {
failure::{format_err, Error, ResultExt},
fidl_fuchsia_netemul_sync::{BusMarker, BusProxy, SyncManagerMarker},
fuchsia_async as fasync,
fuchsia_component::client,
fuchsia_syslog::fx_log_info,
std::io::{Read, Write},
std::net::{SocketAddr, TcpListener, TcpStream},
structopt::StructOpt,
};
const BUS_NAME: &str = "test-bus";
const SERVER_NAME: &str = "server";
const CLIENT_NAME: &str = "client";
const HELLO_MSG_REQ: &str = "Hello World from Client!";
const HELLO_MSG_RSP: &str = "Hello World from Server!";
const SERVER_IP: &str = "192.168.0.1";
const PORT: i32 = 8080;
pub struct BusConnection {
bus: BusProxy,
}
impl BusConnection {
pub fn new(client: &str) -> Result<BusConnection, Error> {
let busm = client::connect_to_service::<SyncManagerMarker>()
.context("SyncManager not available")?;
let (bus, busch) = fidl::endpoints::create_proxy::<BusMarker>()?;
busm.bus_subscribe(BUS_NAME, client, busch)?;
Ok(BusConnection { bus })
}
pub async fn wait_for_client(&mut self, expect: &'static str) -> Result<(), Error> {
let _ = await!(self.bus.wait_for_clients(&mut vec![expect].drain(..), 0))?;
Ok(())
}
}
async fn run_server() -> Result<(), Error> {
let listener =
TcpListener::bind(&format!("{}:{}", SERVER_IP, PORT)).context("Can't bind to address")?;
fx_log_info!("Waiting for connections...");
let _bus = BusConnection::new(SERVER_NAME)?;
let (mut stream, remote) = listener.accept().context("Accept failed")?;
fx_log_info!("Accepted connection from {}", remote);
let mut buffer = [0; 512];
let rd = stream.read(&mut buffer).context("read failed")?;
let req = String::from_utf8_lossy(&buffer[0..rd]);
if req != HELLO_MSG_REQ {
return Err(format_err!("Got unexpected request from client: {}", req));
}
fx_log_info!("Got request {}", req);
stream.write(HELLO_MSG_RSP.as_bytes()).context("write failed")?;
stream.flush().context("flush failed")?;
Ok(())
}
async fn run_client() -> Result<(), Error> {
fx_log_info!("Waiting for server...");
let mut bus = BusConnection::new(CLIENT_NAME)?;
let () = await!(bus.wait_for_client(SERVER_NAME))?;
fx_log_info!("Connecting to server...");
let addr: SocketAddr = format!("{}:{}", SERVER_IP, PORT).parse()?;
let mut stream = TcpStream::connect(&addr).context("Tcp connection failed")?;
let request = HELLO_MSG_REQ.as_bytes();
stream.write(request)?;
stream.flush()?;
let mut buffer = [0; 512];
let rd = stream.read(&mut buffer)?;
let rsp = String::from_utf8_lossy(&buffer[0..rd]);
fx_log_info!("Got response {}", rsp);
if rsp != HELLO_MSG_RSP {
return Err(format_err!("Got unexpected echo from server: {}", rsp));
}
Ok(())
}
#[derive(StructOpt, Debug)]
struct Opt {
#[structopt(short = "c")]
is_child: bool,
}
fn main() -> Result<(), Error> {
fuchsia_syslog::init_with_tags(&["easy-netstack-cfg"])?;
fx_log_info!("Started");
let opt = Opt::from_args();
let mut executor = fasync::Executor::new().context("Error creating executor")?;
executor.run_singlethreaded(
async {
if opt.is_child {
await!(run_client())
} else {
await!(run_server())
}
},
)
}