Skip to main content

fidl_fuchsia_net_stack/
fidl_fuchsia_net_stack.rs

1// WARNING: This file is machine generated by fidlgen.
2
3#![warn(clippy::all)]
4#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]
5
6use bitflags::bitflags;
7use fidl::client::QueryResponseFut;
8use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
9use fidl::endpoints::{ControlHandle as _, Responder as _};
10pub use fidl_fuchsia_net_stack_common::*;
11use futures::future::{self, MaybeDone, TryFutureExt};
12use zx_status;
13
14#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
15pub struct StackSetDhcpClientEnabledRequest {
16    pub id: u64,
17    pub enable: bool,
18}
19
20impl fidl::Standalone<fidl::encoding::DefaultFuchsiaResourceDialect>
21    for StackSetDhcpClientEnabledRequest
22{
23}
24
25#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
26pub struct LogMarker;
27
28impl fidl::endpoints::ProtocolMarker for LogMarker {
29    type Proxy = LogProxy;
30    type RequestStream = LogRequestStream;
31    #[cfg(target_os = "fuchsia")]
32    type SynchronousProxy = LogSynchronousProxy;
33
34    const DEBUG_NAME: &'static str = "fuchsia.net.stack.Log";
35}
36impl fidl::endpoints::DiscoverableProtocolMarker for LogMarker {}
37
38pub trait LogProxyInterface: Send + Sync {
39    type SetLogPacketsResponseFut: std::future::Future<Output = Result<(), fidl::Error>> + Send;
40    fn r#set_log_packets(&self, enabled: bool) -> Self::SetLogPacketsResponseFut;
41}
42#[derive(Debug)]
43#[cfg(target_os = "fuchsia")]
44pub struct LogSynchronousProxy {
45    client: fidl::client::sync::Client,
46}
47
48#[cfg(target_os = "fuchsia")]
49impl fidl::endpoints::SynchronousProxy for LogSynchronousProxy {
50    type Proxy = LogProxy;
51    type Protocol = LogMarker;
52
53    fn from_channel(inner: fidl::Channel) -> Self {
54        Self::new(inner)
55    }
56
57    fn into_channel(self) -> fidl::Channel {
58        self.client.into_channel()
59    }
60
61    fn as_channel(&self) -> &fidl::Channel {
62        self.client.as_channel()
63    }
64}
65
66#[cfg(target_os = "fuchsia")]
67impl LogSynchronousProxy {
68    pub fn new(channel: fidl::Channel) -> Self {
69        Self { client: fidl::client::sync::Client::new(channel) }
70    }
71
72    pub fn into_channel(self) -> fidl::Channel {
73        self.client.into_channel()
74    }
75
76    /// Waits until an event arrives and returns it. It is safe for other
77    /// threads to make concurrent requests while waiting for an event.
78    pub fn wait_for_event(&self, deadline: zx::MonotonicInstant) -> Result<LogEvent, fidl::Error> {
79        LogEvent::decode(self.client.wait_for_event::<LogMarker>(deadline)?)
80    }
81
82    /// Dynamically set packet logging.
83    pub fn r#set_log_packets(
84        &self,
85        mut enabled: bool,
86        ___deadline: zx::MonotonicInstant,
87    ) -> Result<(), fidl::Error> {
88        let _response = self
89            .client
90            .send_query::<LogSetLogPacketsRequest, fidl::encoding::EmptyPayload, LogMarker>(
91                (enabled,),
92                0x2176044cba5f378e,
93                fidl::encoding::DynamicFlags::empty(),
94                ___deadline,
95            )?;
96        Ok(_response)
97    }
98}
99
100#[cfg(target_os = "fuchsia")]
101impl From<LogSynchronousProxy> for zx::NullableHandle {
102    fn from(value: LogSynchronousProxy) -> Self {
103        value.into_channel().into()
104    }
105}
106
107#[cfg(target_os = "fuchsia")]
108impl From<fidl::Channel> for LogSynchronousProxy {
109    fn from(value: fidl::Channel) -> Self {
110        Self::new(value)
111    }
112}
113
114#[cfg(target_os = "fuchsia")]
115impl fidl::endpoints::FromClient for LogSynchronousProxy {
116    type Protocol = LogMarker;
117
118    fn from_client(value: fidl::endpoints::ClientEnd<LogMarker>) -> Self {
119        Self::new(value.into_channel())
120    }
121}
122
123#[derive(Debug, Clone)]
124pub struct LogProxy {
125    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
126}
127
128impl fidl::endpoints::Proxy for LogProxy {
129    type Protocol = LogMarker;
130
131    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
132        Self::new(inner)
133    }
134
135    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
136        self.client.into_channel().map_err(|client| Self { client })
137    }
138
139    fn as_channel(&self) -> &::fidl::AsyncChannel {
140        self.client.as_channel()
141    }
142}
143
144impl LogProxy {
145    /// Create a new Proxy for fuchsia.net.stack/Log.
146    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
147        let protocol_name = <LogMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
148        Self { client: fidl::client::Client::new(channel, protocol_name) }
149    }
150
151    /// Get a Stream of events from the remote end of the protocol.
152    ///
153    /// # Panics
154    ///
155    /// Panics if the event stream was already taken.
156    pub fn take_event_stream(&self) -> LogEventStream {
157        LogEventStream { event_receiver: self.client.take_event_receiver() }
158    }
159
160    /// Dynamically set packet logging.
161    pub fn r#set_log_packets(
162        &self,
163        mut enabled: bool,
164    ) -> fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect> {
165        LogProxyInterface::r#set_log_packets(self, enabled)
166    }
167}
168
169impl LogProxyInterface for LogProxy {
170    type SetLogPacketsResponseFut =
171        fidl::client::QueryResponseFut<(), fidl::encoding::DefaultFuchsiaResourceDialect>;
172    fn r#set_log_packets(&self, mut enabled: bool) -> Self::SetLogPacketsResponseFut {
173        fn _decode(
174            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
175        ) -> Result<(), fidl::Error> {
176            let _response = fidl::client::decode_transaction_body::<
177                fidl::encoding::EmptyPayload,
178                fidl::encoding::DefaultFuchsiaResourceDialect,
179                0x2176044cba5f378e,
180            >(_buf?)?;
181            Ok(_response)
182        }
183        self.client.send_query_and_decode::<LogSetLogPacketsRequest, ()>(
184            (enabled,),
185            0x2176044cba5f378e,
186            fidl::encoding::DynamicFlags::empty(),
187            _decode,
188        )
189    }
190}
191
192pub struct LogEventStream {
193    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
194}
195
196impl std::marker::Unpin for LogEventStream {}
197
198impl futures::stream::FusedStream for LogEventStream {
199    fn is_terminated(&self) -> bool {
200        self.event_receiver.is_terminated()
201    }
202}
203
204impl futures::Stream for LogEventStream {
205    type Item = Result<LogEvent, fidl::Error>;
206
207    fn poll_next(
208        mut self: std::pin::Pin<&mut Self>,
209        cx: &mut std::task::Context<'_>,
210    ) -> std::task::Poll<Option<Self::Item>> {
211        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
212            &mut self.event_receiver,
213            cx
214        )?) {
215            Some(buf) => std::task::Poll::Ready(Some(LogEvent::decode(buf))),
216            None => std::task::Poll::Ready(None),
217        }
218    }
219}
220
221#[derive(Debug)]
222pub enum LogEvent {}
223
224impl LogEvent {
225    /// Decodes a message buffer as a [`LogEvent`].
226    fn decode(
227        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
228    ) -> Result<LogEvent, fidl::Error> {
229        let (bytes, _handles) = buf.split_mut();
230        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
231        debug_assert_eq!(tx_header.tx_id, 0);
232        match tx_header.ordinal {
233            _ => Err(fidl::Error::UnknownOrdinal {
234                ordinal: tx_header.ordinal,
235                protocol_name: <LogMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
236            }),
237        }
238    }
239}
240
241/// A Stream of incoming requests for fuchsia.net.stack/Log.
242pub struct LogRequestStream {
243    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
244    is_terminated: bool,
245}
246
247impl std::marker::Unpin for LogRequestStream {}
248
249impl futures::stream::FusedStream for LogRequestStream {
250    fn is_terminated(&self) -> bool {
251        self.is_terminated
252    }
253}
254
255impl fidl::endpoints::RequestStream for LogRequestStream {
256    type Protocol = LogMarker;
257    type ControlHandle = LogControlHandle;
258
259    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
260        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
261    }
262
263    fn control_handle(&self) -> Self::ControlHandle {
264        LogControlHandle { inner: self.inner.clone() }
265    }
266
267    fn into_inner(
268        self,
269    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
270    {
271        (self.inner, self.is_terminated)
272    }
273
274    fn from_inner(
275        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
276        is_terminated: bool,
277    ) -> Self {
278        Self { inner, is_terminated }
279    }
280}
281
282impl futures::Stream for LogRequestStream {
283    type Item = Result<LogRequest, fidl::Error>;
284
285    fn poll_next(
286        mut self: std::pin::Pin<&mut Self>,
287        cx: &mut std::task::Context<'_>,
288    ) -> std::task::Poll<Option<Self::Item>> {
289        let this = &mut *self;
290        if this.inner.check_shutdown(cx) {
291            this.is_terminated = true;
292            return std::task::Poll::Ready(None);
293        }
294        if this.is_terminated {
295            panic!("polled LogRequestStream after completion");
296        }
297        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
298            |bytes, handles| {
299                match this.inner.channel().read_etc(cx, bytes, handles) {
300                    std::task::Poll::Ready(Ok(())) => {}
301                    std::task::Poll::Pending => return std::task::Poll::Pending,
302                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
303                        this.is_terminated = true;
304                        return std::task::Poll::Ready(None);
305                    }
306                    std::task::Poll::Ready(Err(e)) => {
307                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
308                            e.into(),
309                        ))));
310                    }
311                }
312
313                // A message has been received from the channel
314                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
315
316                std::task::Poll::Ready(Some(match header.ordinal {
317                    0x2176044cba5f378e => {
318                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
319                        let mut req = fidl::new_empty!(
320                            LogSetLogPacketsRequest,
321                            fidl::encoding::DefaultFuchsiaResourceDialect
322                        );
323                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<LogSetLogPacketsRequest>(&header, _body_bytes, handles, &mut req)?;
324                        let control_handle = LogControlHandle { inner: this.inner.clone() };
325                        Ok(LogRequest::SetLogPackets {
326                            enabled: req.enabled,
327
328                            responder: LogSetLogPacketsResponder {
329                                control_handle: std::mem::ManuallyDrop::new(control_handle),
330                                tx_id: header.tx_id,
331                            },
332                        })
333                    }
334                    _ => Err(fidl::Error::UnknownOrdinal {
335                        ordinal: header.ordinal,
336                        protocol_name: <LogMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
337                    }),
338                }))
339            },
340        )
341    }
342}
343
344#[derive(Debug)]
345pub enum LogRequest {
346    /// Dynamically set packet logging.
347    SetLogPackets { enabled: bool, responder: LogSetLogPacketsResponder },
348}
349
350impl LogRequest {
351    #[allow(irrefutable_let_patterns)]
352    pub fn into_set_log_packets(self) -> Option<(bool, LogSetLogPacketsResponder)> {
353        if let LogRequest::SetLogPackets { enabled, responder } = self {
354            Some((enabled, responder))
355        } else {
356            None
357        }
358    }
359
360    /// Name of the method defined in FIDL
361    pub fn method_name(&self) -> &'static str {
362        match *self {
363            LogRequest::SetLogPackets { .. } => "set_log_packets",
364        }
365    }
366}
367
368#[derive(Debug, Clone)]
369pub struct LogControlHandle {
370    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
371}
372
373impl LogControlHandle {
374    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
375        self.inner.shutdown_with_epitaph(status.into())
376    }
377}
378
379impl fidl::endpoints::ControlHandle for LogControlHandle {
380    fn shutdown(&self) {
381        self.inner.shutdown()
382    }
383
384    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
385        self.inner.shutdown_with_epitaph(status)
386    }
387
388    fn is_closed(&self) -> bool {
389        self.inner.channel().is_closed()
390    }
391    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
392        self.inner.channel().on_closed()
393    }
394
395    #[cfg(target_os = "fuchsia")]
396    fn signal_peer(
397        &self,
398        clear_mask: zx::Signals,
399        set_mask: zx::Signals,
400    ) -> Result<(), zx_status::Status> {
401        use fidl::Peered;
402        self.inner.channel().signal_peer(clear_mask, set_mask)
403    }
404}
405
406impl LogControlHandle {}
407
408#[must_use = "FIDL methods require a response to be sent"]
409#[derive(Debug)]
410pub struct LogSetLogPacketsResponder {
411    control_handle: std::mem::ManuallyDrop<LogControlHandle>,
412    tx_id: u32,
413}
414
415/// Set the the channel to be shutdown (see [`LogControlHandle::shutdown`])
416/// if the responder is dropped without sending a response, so that the client
417/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
418impl std::ops::Drop for LogSetLogPacketsResponder {
419    fn drop(&mut self) {
420        self.control_handle.shutdown();
421        // Safety: drops once, never accessed again
422        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
423    }
424}
425
426impl fidl::endpoints::Responder for LogSetLogPacketsResponder {
427    type ControlHandle = LogControlHandle;
428
429    fn control_handle(&self) -> &LogControlHandle {
430        &self.control_handle
431    }
432
433    fn drop_without_shutdown(mut self) {
434        // Safety: drops once, never accessed again due to mem::forget
435        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
436        // Prevent Drop from running (which would shut down the channel)
437        std::mem::forget(self);
438    }
439}
440
441impl LogSetLogPacketsResponder {
442    /// Sends a response to the FIDL transaction.
443    ///
444    /// Sets the channel to shutdown if an error occurs.
445    pub fn send(self) -> Result<(), fidl::Error> {
446        let _result = self.send_raw();
447        if _result.is_err() {
448            self.control_handle.shutdown();
449        }
450        self.drop_without_shutdown();
451        _result
452    }
453
454    /// Similar to "send" but does not shutdown the channel if an error occurs.
455    pub fn send_no_shutdown_on_err(self) -> Result<(), fidl::Error> {
456        let _result = self.send_raw();
457        self.drop_without_shutdown();
458        _result
459    }
460
461    fn send_raw(&self) -> Result<(), fidl::Error> {
462        self.control_handle.inner.send::<fidl::encoding::EmptyPayload>(
463            (),
464            self.tx_id,
465            0x2176044cba5f378e,
466            fidl::encoding::DynamicFlags::empty(),
467        )
468    }
469}
470
471#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
472pub struct StackMarker;
473
474impl fidl::endpoints::ProtocolMarker for StackMarker {
475    type Proxy = StackProxy;
476    type RequestStream = StackRequestStream;
477    #[cfg(target_os = "fuchsia")]
478    type SynchronousProxy = StackSynchronousProxy;
479
480    const DEBUG_NAME: &'static str = "fuchsia.net.stack.Stack";
481}
482impl fidl::endpoints::DiscoverableProtocolMarker for StackMarker {}
483pub type StackSetDhcpClientEnabledResult = Result<(), Error>;
484
485pub trait StackProxyInterface: Send + Sync {
486    type SetDhcpClientEnabledResponseFut: std::future::Future<Output = Result<StackSetDhcpClientEnabledResult, fidl::Error>>
487        + Send;
488    fn r#set_dhcp_client_enabled(
489        &self,
490        id: u64,
491        enable: bool,
492    ) -> Self::SetDhcpClientEnabledResponseFut;
493}
494#[derive(Debug)]
495#[cfg(target_os = "fuchsia")]
496pub struct StackSynchronousProxy {
497    client: fidl::client::sync::Client,
498}
499
500#[cfg(target_os = "fuchsia")]
501impl fidl::endpoints::SynchronousProxy for StackSynchronousProxy {
502    type Proxy = StackProxy;
503    type Protocol = StackMarker;
504
505    fn from_channel(inner: fidl::Channel) -> Self {
506        Self::new(inner)
507    }
508
509    fn into_channel(self) -> fidl::Channel {
510        self.client.into_channel()
511    }
512
513    fn as_channel(&self) -> &fidl::Channel {
514        self.client.as_channel()
515    }
516}
517
518#[cfg(target_os = "fuchsia")]
519impl StackSynchronousProxy {
520    pub fn new(channel: fidl::Channel) -> Self {
521        Self { client: fidl::client::sync::Client::new(channel) }
522    }
523
524    pub fn into_channel(self) -> fidl::Channel {
525        self.client.into_channel()
526    }
527
528    /// Waits until an event arrives and returns it. It is safe for other
529    /// threads to make concurrent requests while waiting for an event.
530    pub fn wait_for_event(
531        &self,
532        deadline: zx::MonotonicInstant,
533    ) -> Result<StackEvent, fidl::Error> {
534        StackEvent::decode(self.client.wait_for_event::<StackMarker>(deadline)?)
535    }
536
537    /// Enables or disables the DHCP client on an interface.
538    /// TODO(https://fxbug.dev/42162065): Remove this once the DHCP client is moved
539    /// out of the netstack.
540    pub fn r#set_dhcp_client_enabled(
541        &self,
542        mut id: u64,
543        mut enable: bool,
544        ___deadline: zx::MonotonicInstant,
545    ) -> Result<StackSetDhcpClientEnabledResult, fidl::Error> {
546        let _response = self.client.send_query::<
547            StackSetDhcpClientEnabledRequest,
548            fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>,
549            StackMarker,
550        >(
551            (id, enable,),
552            0x6dead3a6025b0543,
553            fidl::encoding::DynamicFlags::empty(),
554            ___deadline,
555        )?;
556        Ok(_response.map(|x| x))
557    }
558}
559
560#[cfg(target_os = "fuchsia")]
561impl From<StackSynchronousProxy> for zx::NullableHandle {
562    fn from(value: StackSynchronousProxy) -> Self {
563        value.into_channel().into()
564    }
565}
566
567#[cfg(target_os = "fuchsia")]
568impl From<fidl::Channel> for StackSynchronousProxy {
569    fn from(value: fidl::Channel) -> Self {
570        Self::new(value)
571    }
572}
573
574#[cfg(target_os = "fuchsia")]
575impl fidl::endpoints::FromClient for StackSynchronousProxy {
576    type Protocol = StackMarker;
577
578    fn from_client(value: fidl::endpoints::ClientEnd<StackMarker>) -> Self {
579        Self::new(value.into_channel())
580    }
581}
582
583#[derive(Debug, Clone)]
584pub struct StackProxy {
585    client: fidl::client::Client<fidl::encoding::DefaultFuchsiaResourceDialect>,
586}
587
588impl fidl::endpoints::Proxy for StackProxy {
589    type Protocol = StackMarker;
590
591    fn from_channel(inner: ::fidl::AsyncChannel) -> Self {
592        Self::new(inner)
593    }
594
595    fn into_channel(self) -> Result<::fidl::AsyncChannel, Self> {
596        self.client.into_channel().map_err(|client| Self { client })
597    }
598
599    fn as_channel(&self) -> &::fidl::AsyncChannel {
600        self.client.as_channel()
601    }
602}
603
604impl StackProxy {
605    /// Create a new Proxy for fuchsia.net.stack/Stack.
606    pub fn new(channel: ::fidl::AsyncChannel) -> Self {
607        let protocol_name = <StackMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME;
608        Self { client: fidl::client::Client::new(channel, protocol_name) }
609    }
610
611    /// Get a Stream of events from the remote end of the protocol.
612    ///
613    /// # Panics
614    ///
615    /// Panics if the event stream was already taken.
616    pub fn take_event_stream(&self) -> StackEventStream {
617        StackEventStream { event_receiver: self.client.take_event_receiver() }
618    }
619
620    /// Enables or disables the DHCP client on an interface.
621    /// TODO(https://fxbug.dev/42162065): Remove this once the DHCP client is moved
622    /// out of the netstack.
623    pub fn r#set_dhcp_client_enabled(
624        &self,
625        mut id: u64,
626        mut enable: bool,
627    ) -> fidl::client::QueryResponseFut<
628        StackSetDhcpClientEnabledResult,
629        fidl::encoding::DefaultFuchsiaResourceDialect,
630    > {
631        StackProxyInterface::r#set_dhcp_client_enabled(self, id, enable)
632    }
633}
634
635impl StackProxyInterface for StackProxy {
636    type SetDhcpClientEnabledResponseFut = fidl::client::QueryResponseFut<
637        StackSetDhcpClientEnabledResult,
638        fidl::encoding::DefaultFuchsiaResourceDialect,
639    >;
640    fn r#set_dhcp_client_enabled(
641        &self,
642        mut id: u64,
643        mut enable: bool,
644    ) -> Self::SetDhcpClientEnabledResponseFut {
645        fn _decode(
646            mut _buf: Result<<fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc, fidl::Error>,
647        ) -> Result<StackSetDhcpClientEnabledResult, fidl::Error> {
648            let _response = fidl::client::decode_transaction_body::<
649                fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>,
650                fidl::encoding::DefaultFuchsiaResourceDialect,
651                0x6dead3a6025b0543,
652            >(_buf?)?;
653            Ok(_response.map(|x| x))
654        }
655        self.client.send_query_and_decode::<
656            StackSetDhcpClientEnabledRequest,
657            StackSetDhcpClientEnabledResult,
658        >(
659            (id, enable,),
660            0x6dead3a6025b0543,
661            fidl::encoding::DynamicFlags::empty(),
662            _decode,
663        )
664    }
665}
666
667pub struct StackEventStream {
668    event_receiver: fidl::client::EventReceiver<fidl::encoding::DefaultFuchsiaResourceDialect>,
669}
670
671impl std::marker::Unpin for StackEventStream {}
672
673impl futures::stream::FusedStream for StackEventStream {
674    fn is_terminated(&self) -> bool {
675        self.event_receiver.is_terminated()
676    }
677}
678
679impl futures::Stream for StackEventStream {
680    type Item = Result<StackEvent, fidl::Error>;
681
682    fn poll_next(
683        mut self: std::pin::Pin<&mut Self>,
684        cx: &mut std::task::Context<'_>,
685    ) -> std::task::Poll<Option<Self::Item>> {
686        match futures::ready!(futures::stream::StreamExt::poll_next_unpin(
687            &mut self.event_receiver,
688            cx
689        )?) {
690            Some(buf) => std::task::Poll::Ready(Some(StackEvent::decode(buf))),
691            None => std::task::Poll::Ready(None),
692        }
693    }
694}
695
696#[derive(Debug)]
697pub enum StackEvent {}
698
699impl StackEvent {
700    /// Decodes a message buffer as a [`StackEvent`].
701    fn decode(
702        mut buf: <fidl::encoding::DefaultFuchsiaResourceDialect as fidl::encoding::ResourceDialect>::MessageBufEtc,
703    ) -> Result<StackEvent, fidl::Error> {
704        let (bytes, _handles) = buf.split_mut();
705        let (tx_header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
706        debug_assert_eq!(tx_header.tx_id, 0);
707        match tx_header.ordinal {
708            _ => Err(fidl::Error::UnknownOrdinal {
709                ordinal: tx_header.ordinal,
710                protocol_name: <StackMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
711            }),
712        }
713    }
714}
715
716/// A Stream of incoming requests for fuchsia.net.stack/Stack.
717pub struct StackRequestStream {
718    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
719    is_terminated: bool,
720}
721
722impl std::marker::Unpin for StackRequestStream {}
723
724impl futures::stream::FusedStream for StackRequestStream {
725    fn is_terminated(&self) -> bool {
726        self.is_terminated
727    }
728}
729
730impl fidl::endpoints::RequestStream for StackRequestStream {
731    type Protocol = StackMarker;
732    type ControlHandle = StackControlHandle;
733
734    fn from_channel(channel: ::fidl::AsyncChannel) -> Self {
735        Self { inner: std::sync::Arc::new(fidl::ServeInner::new(channel)), is_terminated: false }
736    }
737
738    fn control_handle(&self) -> Self::ControlHandle {
739        StackControlHandle { inner: self.inner.clone() }
740    }
741
742    fn into_inner(
743        self,
744    ) -> (::std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>, bool)
745    {
746        (self.inner, self.is_terminated)
747    }
748
749    fn from_inner(
750        inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
751        is_terminated: bool,
752    ) -> Self {
753        Self { inner, is_terminated }
754    }
755}
756
757impl futures::Stream for StackRequestStream {
758    type Item = Result<StackRequest, fidl::Error>;
759
760    fn poll_next(
761        mut self: std::pin::Pin<&mut Self>,
762        cx: &mut std::task::Context<'_>,
763    ) -> std::task::Poll<Option<Self::Item>> {
764        let this = &mut *self;
765        if this.inner.check_shutdown(cx) {
766            this.is_terminated = true;
767            return std::task::Poll::Ready(None);
768        }
769        if this.is_terminated {
770            panic!("polled StackRequestStream after completion");
771        }
772        fidl::encoding::with_tls_decode_buf::<_, fidl::encoding::DefaultFuchsiaResourceDialect>(
773            |bytes, handles| {
774                match this.inner.channel().read_etc(cx, bytes, handles) {
775                    std::task::Poll::Ready(Ok(())) => {}
776                    std::task::Poll::Pending => return std::task::Poll::Pending,
777                    std::task::Poll::Ready(Err(zx_status::Status::PEER_CLOSED)) => {
778                        this.is_terminated = true;
779                        return std::task::Poll::Ready(None);
780                    }
781                    std::task::Poll::Ready(Err(e)) => {
782                        return std::task::Poll::Ready(Some(Err(fidl::Error::ServerRequestRead(
783                            e.into(),
784                        ))));
785                    }
786                }
787
788                // A message has been received from the channel
789                let (header, _body_bytes) = fidl::encoding::decode_transaction_header(bytes)?;
790
791                std::task::Poll::Ready(Some(match header.ordinal {
792                    0x6dead3a6025b0543 => {
793                        header.validate_request_tx_id(fidl::MethodType::TwoWay)?;
794                        let mut req = fidl::new_empty!(
795                            StackSetDhcpClientEnabledRequest,
796                            fidl::encoding::DefaultFuchsiaResourceDialect
797                        );
798                        fidl::encoding::Decoder::<fidl::encoding::DefaultFuchsiaResourceDialect>::decode_into::<StackSetDhcpClientEnabledRequest>(&header, _body_bytes, handles, &mut req)?;
799                        let control_handle = StackControlHandle { inner: this.inner.clone() };
800                        Ok(StackRequest::SetDhcpClientEnabled {
801                            id: req.id,
802                            enable: req.enable,
803
804                            responder: StackSetDhcpClientEnabledResponder {
805                                control_handle: std::mem::ManuallyDrop::new(control_handle),
806                                tx_id: header.tx_id,
807                            },
808                        })
809                    }
810                    _ => Err(fidl::Error::UnknownOrdinal {
811                        ordinal: header.ordinal,
812                        protocol_name: <StackMarker as fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
813                    }),
814                }))
815            },
816        )
817    }
818}
819
820#[derive(Debug)]
821pub enum StackRequest {
822    /// Enables or disables the DHCP client on an interface.
823    /// TODO(https://fxbug.dev/42162065): Remove this once the DHCP client is moved
824    /// out of the netstack.
825    SetDhcpClientEnabled { id: u64, enable: bool, responder: StackSetDhcpClientEnabledResponder },
826}
827
828impl StackRequest {
829    #[allow(irrefutable_let_patterns)]
830    pub fn into_set_dhcp_client_enabled(
831        self,
832    ) -> Option<(u64, bool, StackSetDhcpClientEnabledResponder)> {
833        if let StackRequest::SetDhcpClientEnabled { id, enable, responder } = self {
834            Some((id, enable, responder))
835        } else {
836            None
837        }
838    }
839
840    /// Name of the method defined in FIDL
841    pub fn method_name(&self) -> &'static str {
842        match *self {
843            StackRequest::SetDhcpClientEnabled { .. } => "set_dhcp_client_enabled",
844        }
845    }
846}
847
848#[derive(Debug, Clone)]
849pub struct StackControlHandle {
850    inner: std::sync::Arc<fidl::ServeInner<fidl::encoding::DefaultFuchsiaResourceDialect>>,
851}
852
853impl StackControlHandle {
854    pub fn shutdown_with_epitaph(&self, status: impl Into<fidl::Epitaph>) {
855        self.inner.shutdown_with_epitaph(status.into())
856    }
857}
858
859impl fidl::endpoints::ControlHandle for StackControlHandle {
860    fn shutdown(&self) {
861        self.inner.shutdown()
862    }
863
864    fn shutdown_with_epitaph(&self, status: fidl::Epitaph) {
865        self.inner.shutdown_with_epitaph(status)
866    }
867
868    fn is_closed(&self) -> bool {
869        self.inner.channel().is_closed()
870    }
871    fn on_closed(&self) -> fidl::OnSignalsRef<'_> {
872        self.inner.channel().on_closed()
873    }
874
875    #[cfg(target_os = "fuchsia")]
876    fn signal_peer(
877        &self,
878        clear_mask: zx::Signals,
879        set_mask: zx::Signals,
880    ) -> Result<(), zx_status::Status> {
881        use fidl::Peered;
882        self.inner.channel().signal_peer(clear_mask, set_mask)
883    }
884}
885
886impl StackControlHandle {}
887
888#[must_use = "FIDL methods require a response to be sent"]
889#[derive(Debug)]
890pub struct StackSetDhcpClientEnabledResponder {
891    control_handle: std::mem::ManuallyDrop<StackControlHandle>,
892    tx_id: u32,
893}
894
895/// Set the the channel to be shutdown (see [`StackControlHandle::shutdown`])
896/// if the responder is dropped without sending a response, so that the client
897/// doesn't hang. To prevent this behavior, call `drop_without_shutdown`.
898impl std::ops::Drop for StackSetDhcpClientEnabledResponder {
899    fn drop(&mut self) {
900        self.control_handle.shutdown();
901        // Safety: drops once, never accessed again
902        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
903    }
904}
905
906impl fidl::endpoints::Responder for StackSetDhcpClientEnabledResponder {
907    type ControlHandle = StackControlHandle;
908
909    fn control_handle(&self) -> &StackControlHandle {
910        &self.control_handle
911    }
912
913    fn drop_without_shutdown(mut self) {
914        // Safety: drops once, never accessed again due to mem::forget
915        unsafe { std::mem::ManuallyDrop::drop(&mut self.control_handle) };
916        // Prevent Drop from running (which would shut down the channel)
917        std::mem::forget(self);
918    }
919}
920
921impl StackSetDhcpClientEnabledResponder {
922    /// Sends a response to the FIDL transaction.
923    ///
924    /// Sets the channel to shutdown if an error occurs.
925    pub fn send(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
926        let _result = self.send_raw(result);
927        if _result.is_err() {
928            self.control_handle.shutdown();
929        }
930        self.drop_without_shutdown();
931        _result
932    }
933
934    /// Similar to "send" but does not shutdown the channel if an error occurs.
935    pub fn send_no_shutdown_on_err(self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
936        let _result = self.send_raw(result);
937        self.drop_without_shutdown();
938        _result
939    }
940
941    fn send_raw(&self, mut result: Result<(), Error>) -> Result<(), fidl::Error> {
942        self.control_handle
943            .inner
944            .send::<fidl::encoding::ResultType<fidl::encoding::EmptyStruct, Error>>(
945                result,
946                self.tx_id,
947                0x6dead3a6025b0543,
948                fidl::encoding::DynamicFlags::empty(),
949            )
950    }
951}
952
953mod internal {
954    use super::*;
955
956    impl fidl::encoding::ResourceTypeMarker for StackSetDhcpClientEnabledRequest {
957        type Borrowed<'a> = &'a mut Self;
958        fn take_or_borrow<'a>(
959            value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned,
960        ) -> Self::Borrowed<'a> {
961            value
962        }
963    }
964
965    unsafe impl fidl::encoding::TypeMarker for StackSetDhcpClientEnabledRequest {
966        type Owned = Self;
967
968        #[inline(always)]
969        fn inline_align(_context: fidl::encoding::Context) -> usize {
970            8
971        }
972
973        #[inline(always)]
974        fn inline_size(_context: fidl::encoding::Context) -> usize {
975            16
976        }
977    }
978
979    unsafe impl
980        fidl::encoding::Encode<
981            StackSetDhcpClientEnabledRequest,
982            fidl::encoding::DefaultFuchsiaResourceDialect,
983        > for &mut StackSetDhcpClientEnabledRequest
984    {
985        #[inline]
986        unsafe fn encode(
987            self,
988            encoder: &mut fidl::encoding::Encoder<
989                '_,
990                fidl::encoding::DefaultFuchsiaResourceDialect,
991            >,
992            offset: usize,
993            _depth: fidl::encoding::Depth,
994        ) -> fidl::Result<()> {
995            encoder.debug_check_bounds::<StackSetDhcpClientEnabledRequest>(offset);
996            // Delegate to tuple encoding.
997            fidl::encoding::Encode::<
998                StackSetDhcpClientEnabledRequest,
999                fidl::encoding::DefaultFuchsiaResourceDialect,
1000            >::encode(
1001                (
1002                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.id),
1003                    <bool as fidl::encoding::ValueTypeMarker>::borrow(&self.enable),
1004                ),
1005                encoder,
1006                offset,
1007                _depth,
1008            )
1009        }
1010    }
1011    unsafe impl<
1012        T0: fidl::encoding::Encode<u64, fidl::encoding::DefaultFuchsiaResourceDialect>,
1013        T1: fidl::encoding::Encode<bool, fidl::encoding::DefaultFuchsiaResourceDialect>,
1014    >
1015        fidl::encoding::Encode<
1016            StackSetDhcpClientEnabledRequest,
1017            fidl::encoding::DefaultFuchsiaResourceDialect,
1018        > for (T0, T1)
1019    {
1020        #[inline]
1021        unsafe fn encode(
1022            self,
1023            encoder: &mut fidl::encoding::Encoder<
1024                '_,
1025                fidl::encoding::DefaultFuchsiaResourceDialect,
1026            >,
1027            offset: usize,
1028            depth: fidl::encoding::Depth,
1029        ) -> fidl::Result<()> {
1030            encoder.debug_check_bounds::<StackSetDhcpClientEnabledRequest>(offset);
1031            // Zero out padding regions. There's no need to apply masks
1032            // because the unmasked parts will be overwritten by fields.
1033            unsafe {
1034                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(8);
1035                (ptr as *mut u64).write_unaligned(0);
1036            }
1037            // Write the fields.
1038            self.0.encode(encoder, offset + 0, depth)?;
1039            self.1.encode(encoder, offset + 8, depth)?;
1040            Ok(())
1041        }
1042    }
1043
1044    impl fidl::encoding::Decode<Self, fidl::encoding::DefaultFuchsiaResourceDialect>
1045        for StackSetDhcpClientEnabledRequest
1046    {
1047        #[inline(always)]
1048        fn new_empty() -> Self {
1049            Self {
1050                id: fidl::new_empty!(u64, fidl::encoding::DefaultFuchsiaResourceDialect),
1051                enable: fidl::new_empty!(bool, fidl::encoding::DefaultFuchsiaResourceDialect),
1052            }
1053        }
1054
1055        #[inline]
1056        unsafe fn decode(
1057            &mut self,
1058            decoder: &mut fidl::encoding::Decoder<
1059                '_,
1060                fidl::encoding::DefaultFuchsiaResourceDialect,
1061            >,
1062            offset: usize,
1063            _depth: fidl::encoding::Depth,
1064        ) -> fidl::Result<()> {
1065            decoder.debug_check_bounds::<Self>(offset);
1066            // Verify that padding bytes are zero.
1067            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(8) };
1068            let padval = unsafe { (ptr as *const u64).read_unaligned() };
1069            let mask = 0xffffffffffffff00u64;
1070            let maskedval = padval & mask;
1071            if maskedval != 0 {
1072                return Err(fidl::Error::NonZeroPadding {
1073                    padding_start: offset + 8 + ((mask as u64).trailing_zeros() / 8) as usize,
1074                });
1075            }
1076            fidl::decode!(
1077                u64,
1078                fidl::encoding::DefaultFuchsiaResourceDialect,
1079                &mut self.id,
1080                decoder,
1081                offset + 0,
1082                _depth
1083            )?;
1084            fidl::decode!(
1085                bool,
1086                fidl::encoding::DefaultFuchsiaResourceDialect,
1087                &mut self.enable,
1088                decoder,
1089                offset + 8,
1090                _depth
1091            )?;
1092            Ok(())
1093        }
1094    }
1095}