1use super::*;
2
3mod types;
4pub use types::*;
5
6mod client;
7pub use client::*;
8
9mod setup;
10pub use setup::*;
11
12mod event_socket;
13use event_socket::*;
14
15const PATH_DEFAULT_SERVER: &str = "/var/run/hostapd/wlan1";
16
17pub struct WifiAp {
19 socket_path: std::path::PathBuf,
21 attach_options: Vec<String>,
23 request_receiver: mpsc::Receiver<Request>,
25 broadcast_sender: broadcast::Sender<Broadcast>,
27 self_sender: mpsc::Sender<Request>,
29 command_timeout: std::time::Duration,
31 attach_retries: usize,
33 attach_retry_delay: std::time::Duration,
35}
36
37impl WifiAp {
38 pub async fn run(&mut self) -> SocketResult {
39 info!("Starting Wifi AP process");
40 let (mut deferred_requests, event_socket) = EventSocket::new(
41 &self.socket_path,
42 &mut self.request_receiver,
43 &self.attach_options,
44 self.command_timeout,
45 self.attach_retries,
46 self.attach_retry_delay,
47 )
48 .await?;
49 let (socket_handle, next_deferred_requests) = SocketHandle::open(
52 &self.socket_path,
53 "mapper_hostapd_sync.sock",
54 &mut self.request_receiver,
55 self.command_timeout,
56 )
57 .await?;
58 deferred_requests.extend(next_deferred_requests);
59 for request in deferred_requests {
60 self.self_sender
61 .send(request)
62 .await
63 .expect("self_sender should never close as same struct owns both ends");
64 }
65 self.broadcast(Broadcast::Ready);
66 self.run_internal(event_socket, socket_handle).await
67 }
68
69 fn broadcast(&self, event: Broadcast) {
70 if self.broadcast_sender.send(event).is_err() {
71 debug!("broadcast listener closed")
72 }
73 }
74
75 async fn run_internal(
76 &mut self,
77 mut event_socket: EventSocket,
78 mut socket_handle: SocketHandle<2048>,
79 ) -> SocketResult {
80 enum EventOrRequest {
81 Event(Event),
82 Request(Option<Request>),
83 }
84
85 loop {
86 let event_or_request = tokio::select!(
87 event = event_socket.recv() => EventOrRequest::Event(event?),
88 request = self.request_receiver.recv() => EventOrRequest::Request(request),
89 );
90 match event_or_request {
91 EventOrRequest::Event(event) => self.handle_event(event),
92 EventOrRequest::Request(request) => match request {
93 Some(Request::Shutdown) => return Ok(()),
94 Some(request) => Self::handle_request(&mut socket_handle, request).await?,
95 None => return Err(error::SocketError::ClientChannelClosed),
96 },
97 }
98 }
99 }
100
101 fn handle_event(&self, event_msg: Event) {
102 match event_msg {
103 Event::ApStaConnected(mac) => self.broadcast(Broadcast::Connected(mac)),
104 Event::ApStaDisconnected(mac) => self.broadcast(Broadcast::Disconnected(mac)),
105 Event::Unknown(msg) => self.broadcast(Broadcast::UnknownEvent(msg)),
106 };
107 }
108
109 async fn handle_request<const N: usize>(
110 socket_handle: &mut SocketHandle<N>,
111 request: Request,
112 ) -> SocketResult {
113 match &request {
116 Request::SetValue(key, _, _) => {
117 debug!("Handling request: SetValue({key:?}, <redacted>)")
118 }
119 _ => debug!("Handling request: {request:?}"),
120 }
121 match request {
122 Request::Custom(custom, response_channel) => {
123 let data_str = socket_handle.request(&custom, TryInto::try_into).await?;
124 debug!("Custom request response: {data_str:?}");
125 let _ = response_channel.send(data_str);
126 }
127 Request::Status(response_channel) => {
128 let status = socket_handle
129 .request("STATUS", Status::from_response)
130 .await?;
131
132 let _ = response_channel.send(status);
133 }
134 Request::Config(response_channel) => {
135 let config = socket_handle
136 .request("GET_CONFIG", Config::from_response)
137 .await?;
138 let _ = response_channel.send(config);
139 }
140 Request::Enable(response_channel) => {
141 let _ = response_channel.send(socket_handle.command(b"ENABLE").await?);
142 }
143 Request::Disable(response_channel) => {
144 let _ = response_channel.send(socket_handle.command(b"DISABLE").await?);
145 }
146 Request::SetValue(key, value, response_channel) => {
147 let request_string = format!("SET {key} {value}");
148 let _ =
149 response_channel.send(socket_handle.command(request_string.as_bytes()).await?);
150 }
151 Request::Shutdown => (), }
153 Ok(())
154 }
155}