rsomeip/endpoint/
command.rs

1use crate::{
2    endpoint::{Error, Result},
3    someip::Message,
4};
5use std::net::SocketAddr;
6use tokio::sync::mpsc;
7
8#[cfg(test)]
9mod tests;
10
11/// Provides asynchronous control over a SOME/IP endpoint.
12pub struct Controller {
13    tx: mpsc::Sender<Command>,
14}
15
16impl Controller {
17    /// Creates a new [`Controller`].
18    pub fn new(sender: mpsc::Sender<Command>) -> Self {
19        Self { tx: sender }
20    }
21
22    /// Requests that the endpoint connects to the given target.
23    ///
24    /// # Errors
25    ///
26    /// Returns an error if the endpoint failed to connect to the target.
27    pub async fn connect(&self, target: SocketAddr) -> Response {
28        self.request(Request::Connect(target)).await
29    }
30
31    /// Requests that the endpoint disconnects from the given target.
32    ///
33    /// # Errors
34    ///
35    /// Returns an error if the endpoint failed to disconnect from the target.
36    pub async fn disconnect(&self, target: SocketAddr) -> Response {
37        self.request(Request::Disconnect(target)).await
38    }
39
40    /// Requests that the endpoint sends the message to the destination.
41    ///
42    /// # Errors
43    ///
44    /// Returns an error if the message could not be sent, either from a serialization error or
45    /// connection issue.
46    pub async fn send(&self, msg: Message, dst: SocketAddr) -> Response {
47        self.request(Request::Send { msg, dst }).await
48    }
49
50    /// Requests that the endpoint relay messages with the given message id.
51    ///
52    /// # Errors
53    ///
54    /// Returns an error if the relay could not be set.
55    pub async fn relay(&self, id: u32, tx: mpsc::Sender<Result<Message>>) -> Response {
56        self.request(Request::Relay { id, tx }).await
57    }
58
59    /// Requests the endpoint to shut down.
60    ///
61    /// # Errors
62    ///
63    /// Returns an error if the endpoint failed to shutdown.
64    pub async fn shutdown(&self) -> Response {
65        self.request(Request::Shutdown).await
66    }
67
68    /// Sends a request to the endpoint and awaits the response.
69    ///
70    /// # Errors
71    ///
72    /// Returns an error if the request could not be sent to the endpoint, or if the response could
73    /// not be received.
74    async fn request(&self, request: Request) -> Response {
75        let (tx, mut rx) = mpsc::channel(1);
76        self.tx
77            .send(Command { request, tx })
78            .await
79            .map_err(|_| Error::Failure("could not send request"))?;
80        rx.recv()
81            .await
82            .ok_or(Error::Failure("could not receive response"))?
83    }
84}
85
86/// Encapsulates a Request with a channel for sending the Response.
87pub struct Command {
88    request: Request,
89    tx: mpsc::Sender<Response>,
90}
91
92impl Command {
93    /// Consumes the command to return the response channel and the request.
94    pub fn into_parts(self) -> (Request, mpsc::Sender<Response>) {
95        (self.request, self.tx)
96    }
97}
98
99/// Operations that an endpoint can be requested to perform.
100#[derive(Debug)]
101pub enum Request {
102    /// Requests that the endpoint connects to the given address.
103    Connect(SocketAddr),
104    /// Requests that the endpoint disconnects from the given address.
105    Disconnect(SocketAddr),
106    /// Requests that the endpoint sends the message to the destination.
107    Send { msg: Message, dst: SocketAddr },
108    /// Requests that the endpoint relay messages with the given message id.
109    Relay {
110        id: u32,
111        tx: mpsc::Sender<Result<Message>>,
112    },
113    /// Requests the endpoint to shut down.
114    Shutdown,
115}
116
117/// A response to a [`Request`].
118pub type Response = Result<()>;