1use core::convert::Infallible as Never;
8
9use derivative::Derivative;
10use log::trace;
11use net_types::ip::{GenericOverIp, Ip, Ipv4, Ipv6};
12use netstack3_base::{CoreTimerContext, HandleableTimer, TimerHandler};
13use netstack3_device::{DeviceLayerTimerId, WeakDeviceId};
14use netstack3_ip::device::{IpDeviceIpExt, IpDeviceTimerId};
15use netstack3_ip::IpLayerTimerId;
16
17use crate::context::CoreCtx;
18use crate::transport::TransportLayerTimerId;
19use crate::BindingsTypes;
20
21pub use netstack3_base::{AtomicInstant, Instant};
22
23#[derive(Derivative, GenericOverIp)]
25#[derivative(
26 Clone(bound = ""),
27 Eq(bound = ""),
28 PartialEq(bound = ""),
29 Hash(bound = ""),
30 Debug(bound = "")
31)]
32#[generic_over_ip()]
33pub struct TimerId<BT: BindingsTypes>(pub(crate) TimerIdInner<BT>);
34
35#[derive(Derivative, GenericOverIp)]
36#[derivative(
37 Clone(bound = ""),
38 Eq(bound = ""),
39 PartialEq(bound = ""),
40 Hash(bound = ""),
41 Debug(bound = "")
42)]
43#[generic_over_ip()]
44pub enum TimerIdInner<BT: BindingsTypes> {
45 DeviceLayer(DeviceLayerTimerId<BT>),
47 TransportLayer(TransportLayerTimerId<BT>),
49 IpLayer(IpLayerTimerId),
51 Ipv4Device(IpDeviceTimerId<Ipv4, WeakDeviceId<BT>, BT>),
53 Ipv6Device(IpDeviceTimerId<Ipv6, WeakDeviceId<BT>, BT>),
55}
56
57impl<BT: BindingsTypes> From<DeviceLayerTimerId<BT>> for TimerId<BT> {
58 fn from(id: DeviceLayerTimerId<BT>) -> TimerId<BT> {
59 TimerId(TimerIdInner::DeviceLayer(id))
60 }
61}
62
63impl<BT: BindingsTypes> From<IpLayerTimerId> for TimerId<BT> {
64 fn from(id: IpLayerTimerId) -> TimerId<BT> {
65 TimerId(TimerIdInner::IpLayer(id))
66 }
67}
68
69impl<BT: BindingsTypes> From<TransportLayerTimerId<BT>> for TimerId<BT> {
70 fn from(id: TransportLayerTimerId<BT>) -> Self {
71 TimerId(TimerIdInner::TransportLayer(id))
72 }
73}
74
75impl<BT: BindingsTypes, I: IpDeviceIpExt> From<IpDeviceTimerId<I, WeakDeviceId<BT>, BT>>
76 for TimerId<BT>
77{
78 fn from(value: IpDeviceTimerId<I, WeakDeviceId<BT>, BT>) -> Self {
79 I::map_ip(
80 value,
81 |v4| TimerId(TimerIdInner::Ipv4Device(v4)),
82 |v6| TimerId(TimerIdInner::Ipv6Device(v6)),
83 )
84 }
85}
86
87impl<CC, BT> HandleableTimer<CC, BT> for TimerId<BT>
88where
89 BT: BindingsTypes,
90 CC: TimerHandler<BT, DeviceLayerTimerId<BT>>
91 + TimerHandler<BT, TransportLayerTimerId<BT>>
92 + TimerHandler<BT, IpLayerTimerId>
93 + TimerHandler<BT, IpDeviceTimerId<Ipv4, WeakDeviceId<BT>, BT>>
94 + TimerHandler<BT, IpDeviceTimerId<Ipv6, WeakDeviceId<BT>, BT>>,
95{
96 fn handle(self, core_ctx: &mut CC, bindings_ctx: &mut BT, timer: BT::UniqueTimerId) {
97 trace!("handle_timer: dispatching timerid: {self:?}");
98 match self {
99 TimerId(TimerIdInner::DeviceLayer(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
100 TimerId(TimerIdInner::TransportLayer(x)) => {
101 core_ctx.handle_timer(bindings_ctx, x, timer)
102 }
103 TimerId(TimerIdInner::IpLayer(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
104 TimerId(TimerIdInner::Ipv4Device(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
105 TimerId(TimerIdInner::Ipv6Device(x)) => core_ctx.handle_timer(bindings_ctx, x, timer),
106 }
107 }
108}
109
110impl<'a, BT, L> CoreTimerContext<Never, BT> for CoreCtx<'a, BT, L>
111where
112 BT: BindingsTypes,
113{
114 fn convert_timer(dispatch_id: Never) -> <BT as netstack3_base::TimerBindingsTypes>::DispatchId {
115 match dispatch_id {}
116 }
117}