2021-11-22 16:28:30 +00:00
|
|
|
use crate::command_processor::*;
|
2022-06-28 03:46:29 +00:00
|
|
|
use crate::tools::*;
|
2022-07-01 16:13:52 +00:00
|
|
|
use serde::de::DeserializeOwned;
|
2021-11-22 16:28:30 +00:00
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::net::SocketAddr;
|
|
|
|
use std::rc::Rc;
|
2023-06-08 01:55:23 +00:00
|
|
|
use stop_token::{future::FutureExt as _, StopSource, StopToken};
|
|
|
|
|
|
|
|
use veilid_tools::*;
|
|
|
|
cfg_if! {
|
|
|
|
if #[cfg(feature="rt-async-std")] {
|
|
|
|
use async_std::io::prelude::BufReadExt;
|
|
|
|
use async_std::io::WriteExt;
|
|
|
|
use async_std::io::BufReader;
|
|
|
|
} else if #[cfg(feature="rt-tokio")] {
|
|
|
|
use tokio::io::AsyncBufReadExt;
|
|
|
|
use tokio::io::AsyncWriteExt;
|
|
|
|
use tokio::io::BufReader;
|
2022-07-01 16:13:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-08 01:55:23 +00:00
|
|
|
// fn map_to_internal_error<T: ToString>(e: T) -> VeilidAPIError {
|
|
|
|
// VeilidAPIError::Internal {
|
|
|
|
// message: e.to_string(),
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// fn decode_api_result<T: DeserializeOwned + fmt::Debug>(
|
|
|
|
// reader: &api_result::Reader,
|
|
|
|
// ) -> VeilidAPIResult<T> {
|
|
|
|
// match reader.which().map_err(map_to_internal_error)? {
|
|
|
|
// api_result::Which::Ok(v) => {
|
|
|
|
// let ok_val = v.map_err(map_to_internal_error)?;
|
|
|
|
// let res: T = veilid_core::deserialize_json(ok_val).map_err(map_to_internal_error)?;
|
|
|
|
// Ok(res)
|
|
|
|
// }
|
|
|
|
// api_result::Which::Err(e) => {
|
|
|
|
// let err_val = e.map_err(map_to_internal_error)?;
|
|
|
|
// let res: VeilidAPIError =
|
|
|
|
// veilid_core::deserialize_json(err_val).map_err(map_to_internal_error)?;
|
|
|
|
// Err(res)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// struct VeilidClientImpl {
|
|
|
|
// comproc: CommandProcessor,
|
|
|
|
// }
|
|
|
|
|
|
|
|
// impl VeilidClientImpl {
|
|
|
|
// pub fn new(comproc: CommandProcessor) -> Self {
|
|
|
|
// Self { comproc }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
2021-11-22 16:28:30 +00:00
|
|
|
|
|
|
|
struct ClientApiConnectionInner {
|
|
|
|
comproc: CommandProcessor,
|
|
|
|
connect_addr: Option<SocketAddr>,
|
2023-06-08 01:55:23 +00:00
|
|
|
server: Option<flume::Sender<String>>,
|
2022-11-16 17:49:53 +00:00
|
|
|
server_settings: Option<String>,
|
2023-06-08 01:55:23 +00:00
|
|
|
disconnector: Option<StopSource>,
|
2021-11-22 16:28:30 +00:00
|
|
|
disconnect_requested: bool,
|
2022-11-03 15:28:29 +00:00
|
|
|
cancel_eventual: Eventual,
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Handle<T> = Rc<RefCell<T>>;
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct ClientApiConnection {
|
|
|
|
inner: Handle<ClientApiConnectionInner>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ClientApiConnection {
|
|
|
|
pub fn new(comproc: CommandProcessor) -> Self {
|
|
|
|
Self {
|
|
|
|
inner: Rc::new(RefCell::new(ClientApiConnectionInner {
|
2021-11-28 02:31:01 +00:00
|
|
|
comproc,
|
2021-11-22 16:28:30 +00:00
|
|
|
connect_addr: None,
|
|
|
|
server: None,
|
2022-11-16 17:49:53 +00:00
|
|
|
server_settings: None,
|
2023-06-08 01:55:23 +00:00
|
|
|
disconnector: None,
|
2021-11-22 16:28:30 +00:00
|
|
|
disconnect_requested: false,
|
2022-11-03 15:28:29 +00:00
|
|
|
cancel_eventual: Eventual::new(),
|
2021-11-22 16:28:30 +00:00
|
|
|
})),
|
|
|
|
}
|
|
|
|
}
|
2022-11-03 15:28:29 +00:00
|
|
|
|
|
|
|
pub fn cancel(&self) {
|
|
|
|
let eventual = {
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
inner.cancel_eventual.clone()
|
|
|
|
};
|
|
|
|
eventual.resolve(); // don't need to await this
|
|
|
|
}
|
|
|
|
|
2023-06-08 01:55:23 +00:00
|
|
|
// async fn process_veilid_state<'a>(
|
|
|
|
// &'a mut self,
|
|
|
|
// veilid_state: VeilidState,
|
|
|
|
// ) -> Result<(), String> {
|
|
|
|
// let mut inner = self.inner.borrow_mut();
|
|
|
|
// inner.comproc.update_attachment(veilid_state.attachment);
|
|
|
|
// inner.comproc.update_network_status(veilid_state.network);
|
|
|
|
// inner.comproc.update_config(veilid_state.config);
|
|
|
|
// Ok(())
|
|
|
|
// }
|
|
|
|
|
|
|
|
async fn process_update(&self, update: json::JsonValue) {
|
|
|
|
let comproc = self.inner.borrow().comproc.clone();
|
|
|
|
let Some(kind) = update["kind"].as_str() else {
|
|
|
|
comproc.log_message(format!("missing update kind: {}", update));
|
|
|
|
return;
|
2023-03-03 15:55:31 +00:00
|
|
|
};
|
2023-06-08 01:55:23 +00:00
|
|
|
match kind {
|
|
|
|
"Log" => {
|
|
|
|
comproc.update_log(update);
|
|
|
|
}
|
|
|
|
"AppMessage" => {
|
|
|
|
comproc.update_app_message(update);
|
|
|
|
}
|
|
|
|
"AppCall" => {
|
|
|
|
comproc.update_app_call(update);
|
|
|
|
}
|
|
|
|
"Attachment" => {
|
|
|
|
comproc.update_attachment(update);
|
|
|
|
}
|
|
|
|
"Network" => {
|
|
|
|
comproc.update_network_status(update);
|
|
|
|
}
|
|
|
|
"Config" => {
|
|
|
|
comproc.update_config(update);
|
|
|
|
}
|
|
|
|
"RouteChange" => {
|
|
|
|
comproc.update_route(update);
|
|
|
|
}
|
|
|
|
"Shutdown" => comproc.update_shutdown(),
|
|
|
|
"ValueChange" => {
|
|
|
|
comproc.update_value_change(update);
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
comproc.log_message(format!("unknown update kind: {}", update));
|
|
|
|
}
|
|
|
|
}
|
2022-06-08 13:33:41 +00:00
|
|
|
}
|
|
|
|
|
2023-06-08 01:55:23 +00:00
|
|
|
// async fn spawn_rpc_system(
|
|
|
|
// &mut self,
|
|
|
|
// connect_addr: SocketAddr,
|
|
|
|
// mut rpc_system: RpcSystem<rpc_twoparty_capnp::Side>,
|
|
|
|
// ) -> Result<(), String> {
|
|
|
|
// let mut request;
|
|
|
|
// {
|
|
|
|
// let mut inner = self.inner.borrow_mut();
|
|
|
|
|
|
|
|
// // Get the bootstrap server connection object
|
|
|
|
// inner.server = Some(Rc::new(RefCell::new(
|
|
|
|
// rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server),
|
|
|
|
// )));
|
|
|
|
|
|
|
|
// // Store our disconnector future for later (must happen after bootstrap, contrary to documentation)
|
|
|
|
// inner.disconnector = Some(rpc_system.get_disconnector());
|
|
|
|
|
|
|
|
// // Get a client object to pass to the server for status update callbacks
|
|
|
|
// let client = capnp_rpc::new_client(VeilidClientImpl::new(inner.comproc.clone()));
|
|
|
|
|
|
|
|
// // Register our client and get a registration object back
|
|
|
|
// request = inner
|
|
|
|
// .server
|
|
|
|
// .as_ref()
|
|
|
|
// .unwrap()
|
|
|
|
// .borrow_mut()
|
|
|
|
// .register_request();
|
|
|
|
// request.get().set_veilid_client(client);
|
|
|
|
|
|
|
|
// inner
|
|
|
|
// .comproc
|
|
|
|
// .set_connection_state(ConnectionState::Connected(
|
|
|
|
// connect_addr,
|
|
|
|
// std::time::SystemTime::now(),
|
|
|
|
// ));
|
|
|
|
// }
|
|
|
|
|
|
|
|
// let rpc_jh = spawn_local(rpc_system);
|
|
|
|
|
|
|
|
// let reg_res: Result<registration::Client, String> = (async {
|
|
|
|
// // Send the request and get the state object and the registration object
|
|
|
|
// let response = request
|
|
|
|
// .send()
|
|
|
|
// .promise
|
|
|
|
// .await
|
|
|
|
// .map_err(|e| format!("failed to send register request: {}", e))?;
|
|
|
|
// let response = response
|
|
|
|
// .get()
|
|
|
|
// .map_err(|e| format!("failed to get register response: {}", e))?;
|
|
|
|
|
|
|
|
// // Get the registration object, which drops our connection when it is dropped
|
|
|
|
// let registration = response
|
|
|
|
// .get_registration()
|
|
|
|
// .map_err(|e| format!("failed to get registration object: {}", e))?;
|
|
|
|
|
|
|
|
// // Get the initial veilid state
|
|
|
|
// let veilid_state = response
|
|
|
|
// .get_state()
|
|
|
|
// .map_err(|e| format!("failed to get initial veilid state: {}", e))?;
|
|
|
|
|
|
|
|
// // Set up our state for the first time
|
|
|
|
// let veilid_state: VeilidState = deserialize_json(veilid_state)
|
|
|
|
// .map_err(|e| format!("failed to get deserialize veilid state: {}", e))?;
|
|
|
|
// self.process_veilid_state(veilid_state).await?;
|
|
|
|
|
|
|
|
// // Save server settings
|
|
|
|
// let server_settings = response
|
|
|
|
// .get_settings()
|
|
|
|
// .map_err(|e| format!("failed to get initial veilid server settings: {}", e))?
|
|
|
|
// .to_owned();
|
|
|
|
// self.inner.borrow_mut().server_settings = Some(server_settings.clone());
|
|
|
|
|
|
|
|
// // Don't drop the registration, doing so will remove the client
|
|
|
|
// // object mapping from the server which we need for the update backchannel
|
|
|
|
// Ok(registration)
|
|
|
|
// })
|
|
|
|
// .await;
|
|
|
|
|
|
|
|
// let _registration = match reg_res {
|
|
|
|
// Ok(v) => v,
|
|
|
|
// Err(e) => {
|
|
|
|
// rpc_jh.abort().await;
|
|
|
|
// return Err(e);
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
|
|
|
|
// // Wait until rpc system completion or disconnect was requested
|
|
|
|
// let res = rpc_jh.await;
|
|
|
|
// res.map_err(|e| format!("client RPC system error: {}", e))
|
|
|
|
// }
|
|
|
|
|
2022-11-16 17:49:53 +00:00
|
|
|
async fn handle_connection(&mut self, connect_addr: SocketAddr) -> Result<(), String> {
|
2022-06-08 13:33:41 +00:00
|
|
|
trace!("ClientApiConnection::handle_connection");
|
2022-11-16 17:49:53 +00:00
|
|
|
|
2023-06-08 01:55:23 +00:00
|
|
|
let stop_token = {
|
|
|
|
let stop_source = StopSource::new();
|
|
|
|
let token = stop_source.token();
|
|
|
|
let mut inner = self.inner.borrow_mut();
|
|
|
|
inner.connect_addr = Some(connect_addr);
|
|
|
|
inner.disconnector = Some(stop_source);
|
|
|
|
token
|
|
|
|
};
|
|
|
|
|
2022-06-08 13:33:41 +00:00
|
|
|
// Connect the TCP socket
|
2022-06-28 03:46:29 +00:00
|
|
|
let stream = TcpStream::connect(connect_addr)
|
2022-06-08 13:33:41 +00:00
|
|
|
.await
|
|
|
|
.map_err(map_to_string)?;
|
2023-06-08 01:55:23 +00:00
|
|
|
|
2022-06-08 13:33:41 +00:00
|
|
|
// If it succeed, disable nagle algorithm
|
|
|
|
stream.set_nodelay(true).map_err(map_to_string)?;
|
|
|
|
|
2023-06-08 01:55:23 +00:00
|
|
|
// Split the stream
|
2022-06-28 03:46:29 +00:00
|
|
|
cfg_if! {
|
|
|
|
if #[cfg(feature="rt-async-std")] {
|
2022-06-29 14:34:23 +00:00
|
|
|
use futures::AsyncReadExt;
|
2022-06-28 03:46:29 +00:00
|
|
|
let (reader, writer) = stream.split();
|
2023-06-08 01:55:23 +00:00
|
|
|
let mut reader = BufReader::new(reader);
|
2022-06-28 03:46:29 +00:00
|
|
|
} else if #[cfg(feature="rt-tokio")] {
|
|
|
|
let (reader, writer) = stream.into_split();
|
2023-06-08 01:55:23 +00:00
|
|
|
let mut reader = BufReader::new(reader);
|
2022-06-28 03:46:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-08 01:55:23 +00:00
|
|
|
// Process lines
|
|
|
|
let mut line = String::new();
|
|
|
|
while let Ok(r) = reader
|
|
|
|
.read_line(&mut line)
|
|
|
|
.timeout_at(stop_token.clone())
|
|
|
|
.await
|
|
|
|
{
|
|
|
|
match r {
|
|
|
|
Ok(size) => {
|
|
|
|
// Exit on EOF
|
|
|
|
if size == 0 {
|
|
|
|
// Disconnected
|
|
|
|
return Err("Connection closed".to_owned());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
// Disconnected
|
|
|
|
return Err("Connection lost".to_owned());
|
|
|
|
}
|
2022-01-18 23:28:22 +00:00
|
|
|
}
|
2021-11-22 16:28:30 +00:00
|
|
|
|
2023-06-08 01:55:23 +00:00
|
|
|
// Unmarshal json
|
|
|
|
let j = match json::parse(line.trim()) {
|
|
|
|
Ok(v) => v,
|
|
|
|
Err(e) => {
|
|
|
|
error!("failed to parse server response: {}", e);
|
|
|
|
continue;
|
2022-11-03 15:28:29 +00:00
|
|
|
}
|
|
|
|
};
|
2023-06-08 01:55:23 +00:00
|
|
|
|
|
|
|
if j["type"] == "Update" {
|
|
|
|
self.process_update(j).await;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Connection finished
|
|
|
|
Ok(())
|
|
|
|
|
|
|
|
// let rpc_network = Box::new(twoparty::VatNetwork::new(
|
|
|
|
// reader,
|
|
|
|
// writer,
|
|
|
|
// rpc_twoparty_capnp::Side::Client,
|
|
|
|
// Default::default(),
|
|
|
|
// ));
|
|
|
|
|
|
|
|
// // Create the rpc system
|
|
|
|
// let rpc_system = RpcSystem::new(rpc_network, None);
|
|
|
|
|
|
|
|
// // Process the rpc system until we decide we're done
|
|
|
|
// match self.spawn_rpc_system(connect_addr, rpc_system).await {
|
|
|
|
// Ok(()) => {}
|
|
|
|
// Err(e) => {
|
|
|
|
// error!("Failed to spawn client RPC system: {}", e);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // Drop the server and disconnector too (if we still have it)
|
|
|
|
// let mut inner = self.inner.borrow_mut();
|
|
|
|
// let disconnect_requested = inner.disconnect_requested;
|
|
|
|
// inner.server_settings = None;
|
|
|
|
// inner.server = None;
|
|
|
|
// inner.disconnector = None;
|
|
|
|
// inner.disconnect_requested = false;
|
|
|
|
// inner.connect_addr = None;
|
2022-11-03 15:28:29 +00:00
|
|
|
}
|
|
|
|
|
2023-06-08 01:55:23 +00:00
|
|
|
// pub fn cancellable<T>(&mut self, p: Promise<T, capnp::Error>) -> Promise<T, capnp::Error>
|
|
|
|
// where
|
|
|
|
// T: 'static,
|
|
|
|
// {
|
|
|
|
// let (mut cancel_instance, cancel_eventual) = {
|
|
|
|
// let inner = self.inner.borrow();
|
|
|
|
// (
|
|
|
|
// inner.cancel_eventual.instance_empty().fuse(),
|
|
|
|
// inner.cancel_eventual.clone(),
|
|
|
|
// )
|
|
|
|
// };
|
|
|
|
// let mut p = p.fuse();
|
|
|
|
|
|
|
|
// Promise::from_future(async move {
|
|
|
|
// let out = select! {
|
|
|
|
// a = p => {
|
|
|
|
// a
|
|
|
|
// },
|
|
|
|
// _ = cancel_instance => {
|
|
|
|
// Err(capnp::Error::failed("cancelled".into()))
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
// drop(cancel_instance);
|
|
|
|
// cancel_eventual.reset();
|
|
|
|
// out
|
|
|
|
// })
|
|
|
|
// }
|
|
|
|
|
2022-01-18 17:33:14 +00:00
|
|
|
pub async fn server_attach(&mut self) -> Result<(), String> {
|
2021-11-22 16:28:30 +00:00
|
|
|
trace!("ClientApiConnection::server_attach");
|
|
|
|
let server = {
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
inner
|
|
|
|
.server
|
|
|
|
.as_ref()
|
2022-01-18 23:28:22 +00:00
|
|
|
.ok_or_else(|| "Not connected, ignoring attach request".to_owned())?
|
2021-11-22 16:28:30 +00:00
|
|
|
.clone()
|
|
|
|
};
|
|
|
|
let request = server.borrow().attach_request();
|
2022-11-03 15:28:29 +00:00
|
|
|
let response = self
|
|
|
|
.cancellable(request.send().promise)
|
|
|
|
.await
|
|
|
|
.map_err(map_to_string)?;
|
2022-07-01 16:13:52 +00:00
|
|
|
let reader = response
|
|
|
|
.get()
|
|
|
|
.map_err(map_to_string)?
|
|
|
|
.get_result()
|
|
|
|
.map_err(map_to_string)?;
|
2023-05-29 19:24:57 +00:00
|
|
|
let res: VeilidAPIResult<()> = decode_api_result(&reader);
|
2022-07-01 16:13:52 +00:00
|
|
|
res.map_err(map_to_string)
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 17:33:14 +00:00
|
|
|
pub async fn server_detach(&mut self) -> Result<(), String> {
|
2021-11-22 16:28:30 +00:00
|
|
|
trace!("ClientApiConnection::server_detach");
|
|
|
|
let server = {
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
inner
|
|
|
|
.server
|
|
|
|
.as_ref()
|
2022-01-18 23:28:22 +00:00
|
|
|
.ok_or_else(|| "Not connected, ignoring detach request".to_owned())?
|
2021-11-22 16:28:30 +00:00
|
|
|
.clone()
|
|
|
|
};
|
|
|
|
let request = server.borrow().detach_request();
|
2022-11-03 15:28:29 +00:00
|
|
|
let response = self
|
|
|
|
.cancellable(request.send().promise)
|
|
|
|
.await
|
|
|
|
.map_err(map_to_string)?;
|
2022-07-01 16:13:52 +00:00
|
|
|
let reader = response
|
|
|
|
.get()
|
|
|
|
.map_err(map_to_string)?
|
|
|
|
.get_result()
|
|
|
|
.map_err(map_to_string)?;
|
2023-05-29 19:24:57 +00:00
|
|
|
let res: VeilidAPIResult<()> = decode_api_result(&reader);
|
2022-07-01 16:13:52 +00:00
|
|
|
res.map_err(map_to_string)
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 17:33:14 +00:00
|
|
|
pub async fn server_shutdown(&mut self) -> Result<(), String> {
|
2021-11-22 16:28:30 +00:00
|
|
|
trace!("ClientApiConnection::server_shutdown");
|
|
|
|
let server = {
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
inner
|
|
|
|
.server
|
|
|
|
.as_ref()
|
2022-01-18 23:28:22 +00:00
|
|
|
.ok_or_else(|| "Not connected, ignoring attach request".to_owned())?
|
2021-11-22 16:28:30 +00:00
|
|
|
.clone()
|
|
|
|
};
|
|
|
|
let request = server.borrow().shutdown_request();
|
2022-11-03 15:28:29 +00:00
|
|
|
let response = self
|
|
|
|
.cancellable(request.send().promise)
|
|
|
|
.await
|
|
|
|
.map_err(map_to_string)?;
|
2022-01-18 17:33:14 +00:00
|
|
|
response.get().map(drop).map_err(map_to_string)
|
2021-12-11 01:14:33 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 17:33:14 +00:00
|
|
|
pub async fn server_debug(&mut self, what: String) -> Result<String, String> {
|
2021-12-11 01:14:33 +00:00
|
|
|
trace!("ClientApiConnection::server_debug");
|
|
|
|
let server = {
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
inner
|
|
|
|
.server
|
|
|
|
.as_ref()
|
2022-07-01 16:13:52 +00:00
|
|
|
.ok_or_else(|| "Not connected, ignoring debug request".to_owned())?
|
2021-12-11 01:14:33 +00:00
|
|
|
.clone()
|
|
|
|
};
|
|
|
|
let mut request = server.borrow().debug_request();
|
2022-07-01 16:13:52 +00:00
|
|
|
request.get().set_command(&what);
|
2022-11-03 15:28:29 +00:00
|
|
|
let response = self
|
|
|
|
.cancellable(request.send().promise)
|
|
|
|
.await
|
|
|
|
.map_err(map_to_string)?;
|
2022-07-01 16:13:52 +00:00
|
|
|
let reader = response
|
2022-01-18 17:33:14 +00:00
|
|
|
.get()
|
|
|
|
.map_err(map_to_string)?
|
2022-07-01 16:13:52 +00:00
|
|
|
.get_result()
|
|
|
|
.map_err(map_to_string)?;
|
2023-05-29 19:24:57 +00:00
|
|
|
let res: VeilidAPIResult<String> = decode_api_result(&reader);
|
2022-07-01 16:13:52 +00:00
|
|
|
res.map_err(map_to_string)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn server_change_log_level(
|
|
|
|
&mut self,
|
|
|
|
layer: String,
|
|
|
|
log_level: VeilidConfigLogLevel,
|
|
|
|
) -> Result<(), String> {
|
|
|
|
trace!("ClientApiConnection::change_log_level");
|
|
|
|
let server = {
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
inner
|
|
|
|
.server
|
|
|
|
.as_ref()
|
|
|
|
.ok_or_else(|| "Not connected, ignoring change_log_level request".to_owned())?
|
|
|
|
.clone()
|
|
|
|
};
|
|
|
|
let mut request = server.borrow().change_log_level_request();
|
|
|
|
request.get().set_layer(&layer);
|
|
|
|
let log_level_json = veilid_core::serialize_json(&log_level);
|
|
|
|
request.get().set_log_level(&log_level_json);
|
2022-11-03 15:28:29 +00:00
|
|
|
let response = self
|
|
|
|
.cancellable(request.send().promise)
|
|
|
|
.await
|
|
|
|
.map_err(map_to_string)?;
|
2022-07-01 16:13:52 +00:00
|
|
|
let reader = response
|
|
|
|
.get()
|
|
|
|
.map_err(map_to_string)?
|
|
|
|
.get_result()
|
2022-10-01 02:37:55 +00:00
|
|
|
.map_err(map_to_string)?;
|
2023-05-29 19:24:57 +00:00
|
|
|
let res: VeilidAPIResult<()> = decode_api_result(&reader);
|
2022-10-01 02:37:55 +00:00
|
|
|
res.map_err(map_to_string)
|
|
|
|
}
|
|
|
|
|
2022-12-17 02:55:03 +00:00
|
|
|
pub async fn server_appcall_reply(
|
|
|
|
&mut self,
|
|
|
|
id: OperationId,
|
|
|
|
msg: Vec<u8>,
|
|
|
|
) -> Result<(), String> {
|
2022-10-01 02:37:55 +00:00
|
|
|
trace!("ClientApiConnection::appcall_reply");
|
|
|
|
let server = {
|
|
|
|
let inner = self.inner.borrow();
|
|
|
|
inner
|
|
|
|
.server
|
|
|
|
.as_ref()
|
|
|
|
.ok_or_else(|| "Not connected, ignoring change_log_level request".to_owned())?
|
|
|
|
.clone()
|
|
|
|
};
|
|
|
|
let mut request = server.borrow().app_call_reply_request();
|
2022-12-17 02:55:03 +00:00
|
|
|
request.get().set_id(id.as_u64());
|
2022-10-01 02:37:55 +00:00
|
|
|
request.get().set_message(&msg);
|
2022-11-03 15:28:29 +00:00
|
|
|
let response = self
|
|
|
|
.cancellable(request.send().promise)
|
|
|
|
.await
|
|
|
|
.map_err(map_to_string)?;
|
2022-10-01 02:37:55 +00:00
|
|
|
let reader = response
|
|
|
|
.get()
|
|
|
|
.map_err(map_to_string)?
|
|
|
|
.get_result()
|
2022-07-01 16:13:52 +00:00
|
|
|
.map_err(map_to_string)?;
|
2023-05-29 19:24:57 +00:00
|
|
|
let res: VeilidAPIResult<()> = decode_api_result(&reader);
|
2022-07-01 16:13:52 +00:00
|
|
|
res.map_err(map_to_string)
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Start Client API connection
|
2022-01-18 17:33:14 +00:00
|
|
|
pub async fn connect(&mut self, connect_addr: SocketAddr) -> Result<(), String> {
|
2021-11-22 16:28:30 +00:00
|
|
|
trace!("ClientApiConnection::connect");
|
|
|
|
// Save the address to connect to
|
2022-11-16 17:49:53 +00:00
|
|
|
self.handle_connection(connect_addr).await
|
2021-11-22 16:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// End Client API connection
|
|
|
|
pub async fn disconnect(&mut self) {
|
|
|
|
trace!("ClientApiConnection::disconnect");
|
|
|
|
let disconnector = self.inner.borrow_mut().disconnector.take();
|
|
|
|
match disconnector {
|
|
|
|
Some(d) => {
|
|
|
|
self.inner.borrow_mut().disconnect_requested = true;
|
|
|
|
d.await.unwrap();
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
debug!("disconnector doesn't exist");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|