1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::net::IpAddr;
6
7use super::common::{Bandwidth, DataSource, EntityOrigin};
8use super::entity_id::{EntityId, MacAddress};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12#[non_exhaustive]
13pub enum DeviceType {
14 Gateway,
15 Switch,
16 AccessPoint,
17 Other,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22#[non_exhaustive]
23pub enum DeviceState {
24 Online,
25 Offline,
26 PendingAdoption,
27 Updating,
28 GettingReady,
29 Adopting,
30 Deleting,
31 ConnectionInterrupted,
32 Isolated,
33 Unknown,
34}
35
36impl DeviceState {
37 pub fn is_online(&self) -> bool {
38 matches!(self, Self::Online)
39 }
40
41 pub fn is_transitional(&self) -> bool {
42 matches!(
43 self,
44 Self::Updating | Self::GettingReady | Self::Adopting | Self::PendingAdoption
45 )
46 }
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct Port {
52 pub index: u32,
53 pub name: Option<String>,
54 pub state: PortState,
55 pub speed_mbps: Option<u32>,
56 pub max_speed_mbps: Option<u32>,
57 pub connector: Option<PortConnector>,
58 pub poe: Option<PoeInfo>,
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
62pub enum PortState {
63 Up,
64 Down,
65 Unknown,
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
69pub enum PortConnector {
70 Rj45,
71 Sfp,
72 SfpPlus,
73 Sfp28,
74 Qsfp28,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct PoeInfo {
79 pub standard: Option<String>,
80 pub enabled: bool,
81 pub state: PortState,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct Radio {
87 pub frequency_ghz: f32,
88 pub channel: Option<u32>,
89 pub channel_width_mhz: Option<u32>,
90 pub wlan_standard: Option<String>,
91 pub tx_retries_pct: Option<f64>,
92}
93
94#[derive(Debug, Clone, Default, Serialize, Deserialize)]
96pub struct DeviceStats {
97 pub uptime_secs: Option<u64>,
98 pub cpu_utilization_pct: Option<f64>,
99 pub memory_utilization_pct: Option<f64>,
100 pub load_average_1m: Option<f64>,
101 pub load_average_5m: Option<f64>,
102 pub load_average_15m: Option<f64>,
103 pub uplink_bandwidth: Option<Bandwidth>,
104 pub last_heartbeat: Option<DateTime<Utc>>,
105 pub next_heartbeat: Option<DateTime<Utc>>,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
110#[allow(clippy::struct_excessive_bools)]
111pub struct Device {
112 pub id: EntityId,
113 pub mac: MacAddress,
114 pub ip: Option<IpAddr>,
115 pub wan_ipv6: Option<String>,
116 pub name: Option<String>,
117 pub model: Option<String>,
118 pub device_type: DeviceType,
119 pub state: DeviceState,
120
121 pub firmware_version: Option<String>,
123 pub firmware_updatable: bool,
124
125 pub adopted_at: Option<DateTime<Utc>>,
127 pub provisioned_at: Option<DateTime<Utc>>,
128 pub last_seen: Option<DateTime<Utc>>,
129
130 pub serial: Option<String>,
132 pub supported: bool,
133
134 pub ports: Vec<Port>,
136 pub radios: Vec<Radio>,
137
138 pub uplink_device_id: Option<EntityId>,
140 pub uplink_device_mac: Option<MacAddress>,
141
142 pub has_switching: bool,
144 pub has_access_point: bool,
145
146 pub stats: DeviceStats,
148
149 pub client_count: Option<u32>,
151
152 pub origin: Option<EntityOrigin>,
154
155 #[serde(skip)]
156 #[allow(dead_code)]
157 pub(crate) source: DataSource,
158 #[serde(skip)]
159 #[allow(dead_code)]
160 pub(crate) updated_at: DateTime<Utc>,
161}