simple_someip/client/
mod.rs1mod inner;
2mod socket_manager;
3
4use crate::{Error, protocol::Message, traits::PayloadWireFormat};
5use inner::{ControlMessage, Inner};
6use std::net::{Ipv4Addr, SocketAddrV4};
7use tokio::sync::mpsc;
8use tracing::info;
9
10pub enum ClientUpdate<P: PayloadWireFormat> {
11 DiscoveryUpdated(P::SdHeader),
13 Unicast(Message<P>),
15 Error(Error),
17}
18
19impl<P: PayloadWireFormat> std::fmt::Debug for ClientUpdate<P> {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 match self {
22 Self::DiscoveryUpdated(header) => {
23 f.debug_tuple("DiscoveryUpdated").field(header).finish()
24 }
25 Self::Unicast(msg) => f.debug_tuple("Unicast").field(msg).finish(),
26 Self::Error(err) => f.debug_tuple("Error").field(err).finish(),
27 }
28 }
29}
30
31pub struct Client<MessageDefinitions: PayloadWireFormat> {
32 interface: Ipv4Addr,
33 control_sender: mpsc::Sender<inner::ControlMessage<MessageDefinitions>>,
34 update_receiver: mpsc::Receiver<ClientUpdate<MessageDefinitions>>,
35}
36
37impl<MessageDefinitions: PayloadWireFormat> std::fmt::Debug for Client<MessageDefinitions> {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 f.debug_struct("Client")
40 .field("interface", &self.interface)
41 .finish_non_exhaustive()
42 }
43}
44
45impl<MessageDefinitions> Client<MessageDefinitions>
46where
47 MessageDefinitions: PayloadWireFormat + Clone + std::fmt::Debug + 'static,
48{
49 #[must_use]
50 pub fn new(interface: Ipv4Addr) -> Self {
51 let (control_sender, update_receiver) = Inner::spawn(interface);
52
53 Self {
54 interface,
55 control_sender,
56 update_receiver,
57 }
58 }
59
60 pub async fn run(&mut self) -> Option<ClientUpdate<MessageDefinitions>> {
61 self.update_receiver.recv().await
62 }
63
64 #[must_use]
65 pub fn interface(&self) -> Ipv4Addr {
66 self.interface
67 }
68
69 pub async fn set_interface(&mut self, interface: Ipv4Addr) -> Result<(), Error> {
70 let (response, message) = ControlMessage::set_interface(interface);
71 self.control_sender.send(message).await.unwrap();
72 response.await.unwrap()?;
73 self.interface = interface;
74 Ok(())
75 }
76
77 pub async fn bind_discovery(&mut self) -> Result<(), Error> {
78 let (response, message) = ControlMessage::bind_discovery();
79 self.control_sender.send(message).await.unwrap();
80 response.await.unwrap()
81 }
82
83 pub async fn unbind_discovery(&mut self) -> Result<(), Error> {
84 let (response, message) = ControlMessage::unbind_discovery();
85 self.control_sender.send(message).await.unwrap();
86 response.await.unwrap()
87 }
88
89 pub async fn bind_unicast(&mut self) -> Result<u16, Error> {
90 self.bind_unicast_with_port(None).await
91 }
92
93 pub async fn bind_unicast_with_port(&mut self, port: Option<u16>) -> Result<u16, Error> {
94 let (response, message) = ControlMessage::bind_unicast_with_port(port);
95 self.control_sender.send(message).await.unwrap();
96 response.await.unwrap()
97 }
98
99 pub async fn unbind_unicast(&mut self) -> Result<(), Error> {
100 let (response, message) = ControlMessage::unbind_unicast();
101 self.control_sender.send(message).await.unwrap();
102 response.await.unwrap()
103 }
104
105 pub async fn send_sd_message(
106 &mut self,
107 target: SocketAddrV4,
108 sd_header: <MessageDefinitions as PayloadWireFormat>::SdHeader,
109 ) -> Result<(), Error> {
110 let (response, message) = ControlMessage::send_sd(target, sd_header);
111 self.control_sender.send(message).await.unwrap();
112 response.await.unwrap()
113 }
114
115 pub async fn send_message(
116 &mut self,
117 target: SocketAddrV4,
118 message: crate::protocol::Message<MessageDefinitions>,
119 source_port: u16,
120 ) -> Result<MessageDefinitions, Error> {
121 let (response, message) = ControlMessage::send_request(target, message, source_port);
122 self.control_sender.send(message).await.unwrap();
123 response.await.unwrap()
124 }
125
126 pub async fn shut_down(self) {
127 let Self {
128 control_sender,
129 mut update_receiver,
130 ..
131 } = self;
132 drop(control_sender);
133 info!("Shutting Down SOME/IP client");
134 while update_receiver.recv().await.is_some() {
135 info!(".");
136 }
137 }
138}