Skip to main content

netstack3_core/
time.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Types for dealing with time and timers.
6
7use derivative::Derivative;
8use log::trace;
9use net_types::ip::{GenericOverIp, Ip, Ipv4, Ipv6};
10use netstack3_base::{CoreTimerContext, HandleableTimer, TimerHandler};
11use netstack3_device::{DeviceLayerTimerId, WeakDeviceId};
12use netstack3_ip::IpLayerTimerId;
13use netstack3_ip::device::{IpDeviceIpExt, IpDeviceTimerId};
14
15use crate::BindingsTypes;
16use crate::context::CoreCtx;
17use crate::transport::TransportLayerTimerId;
18
19pub use netstack3_base::{AtomicInstant, Instant};
20
21/// The identifier for any timer event.
22#[derive(Derivative, GenericOverIp)]
23#[derivative(
24    Clone(bound = ""),
25    Eq(bound = ""),
26    PartialEq(bound = ""),
27    Hash(bound = ""),
28    Debug(bound = "")
29)]
30#[generic_over_ip()]
31pub struct TimerId<BT: BindingsTypes>(pub(crate) TimerIdInner<BT>);
32
33#[derive(Derivative, GenericOverIp)]
34#[derivative(
35    Clone(bound = ""),
36    Eq(bound = ""),
37    PartialEq(bound = ""),
38    Hash(bound = ""),
39    Debug(bound = "")
40)]
41#[generic_over_ip()]
42pub enum TimerIdInner<BT: BindingsTypes> {
43    /// A timer event in the device layer.
44    DeviceLayer(DeviceLayerTimerId<BT>),
45    /// A timer event in the transport layer.
46    TransportLayer(TransportLayerTimerId<BT>),
47    /// A timer event in the IP layer.
48    IpLayer(IpLayerTimerId),
49    /// A timer event for an IPv4 device.
50    Ipv4Device(IpDeviceTimerId<Ipv4, WeakDeviceId<BT>, BT>),
51    /// A timer event for an IPv6 device.
52    Ipv6Device(IpDeviceTimerId<Ipv6, WeakDeviceId<BT>, BT>),
53}
54
55impl<BT: BindingsTypes> From<DeviceLayerTimerId<BT>> for TimerId<BT> {
56    fn from(id: DeviceLayerTimerId<BT>) -> TimerId<BT> {
57        TimerId(TimerIdInner::DeviceLayer(id))
58    }
59}
60
61impl<BT: BindingsTypes> From<IpLayerTimerId> for TimerId<BT> {
62    fn from(id: IpLayerTimerId) -> TimerId<BT> {
63        TimerId(TimerIdInner::IpLayer(id))
64    }
65}
66
67impl<BT: BindingsTypes> From<TransportLayerTimerId<BT>> for TimerId<BT> {
68    fn from(id: TransportLayerTimerId<BT>) -> Self {
69        TimerId(TimerIdInner::TransportLayer(id))
70    }
71}
72
73impl<BT: BindingsTypes, I: IpDeviceIpExt> From<IpDeviceTimerId<I, WeakDeviceId<BT>, BT>>
74    for TimerId<BT>
75{
76    fn from(value: IpDeviceTimerId<I, WeakDeviceId<BT>, BT>) -> Self {
77        I::map_ip(
78            value,
79            |v4| TimerId(TimerIdInner::Ipv4Device(v4)),
80            |v6| TimerId(TimerIdInner::Ipv6Device(v6)),
81        )
82    }
83}
84
85impl<CC, BT> HandleableTimer<CC, BT> for TimerId<BT>
86where
87    BT: BindingsTypes,
88    CC: TimerHandler<BT, DeviceLayerTimerId<BT>>
89        + TimerHandler<BT, TransportLayerTimerId<BT>>
90        + TimerHandler<BT, IpLayerTimerId>
91        + TimerHandler<BT, IpDeviceTimerId<Ipv4, WeakDeviceId<BT>, BT>>
92        + TimerHandler<BT, IpDeviceTimerId<Ipv6, WeakDeviceId<BT>, BT>>,
93{
94    fn handle(self, core_ctx: &mut CC, bindings_ctx: &mut BT, timer: BT::UniqueTimerId) {
95        trace!("handle_timer: dispatching timerid: {self:?}");
96        match self {
97            TimerId(TimerIdInner::DeviceLayer(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
98            TimerId(TimerIdInner::TransportLayer(x)) => {
99                core_ctx.handle_timer(bindings_ctx, x, timer)
100            }
101            TimerId(TimerIdInner::IpLayer(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
102            TimerId(TimerIdInner::Ipv4Device(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
103            TimerId(TimerIdInner::Ipv6Device(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
104        }
105    }
106}
107
108impl<'a, BT, L> CoreTimerContext<!, BT> for CoreCtx<'a, BT, L>
109where
110    BT: BindingsTypes,
111{
112    fn convert_timer(dispatch_id: !) -> <BT as netstack3_base::TimerBindingsTypes>::DispatchId {
113        match dispatch_id {}
114    }
115}