1
+ #pragma once
2
+
3
+ #include " zephyr/net/dhcpv4.h"
4
+ #include < zephyr/kernel.h>
5
+ #include < zephyr/linker/sections.h>
6
+ #include < errno.h>
7
+ #include < stdio.h>
8
+
9
+ #include < zephyr/net/net_if.h>
10
+ #include < zephyr/net/net_core.h>
11
+ #include < zephyr/net/net_context.h>
12
+ #include < zephyr/net/net_mgmt.h>
13
+
14
+ #include < api/IPAddress.h>
15
+
16
+ #define DHCP_OPTION_NTP (42 )
17
+
18
+ #define LOG_INF (...)
19
+
20
+ #ifdef SPECIALIZE_FOR_ETHERNET
21
+ enum EthernetLinkStatus {
22
+ Unknown,
23
+ LinkON,
24
+ LinkOFF
25
+ };
26
+
27
+ enum EthernetHardwareStatus {
28
+ EthernetNoHardware,
29
+ EthernetOk
30
+ };
31
+ #endif
32
+
33
+ class NetworkInterface {
34
+ private:
35
+ int iface_index = -1 ;
36
+
37
+ uint8_t ntp_server[4 ];
38
+ static struct net_mgmt_event_callback mgmt_cb;
39
+ static struct net_dhcpv4_option_callback dhcp_cb;
40
+
41
+ static void link_handler (struct net_mgmt_event_callback *cb,
42
+ uint32_t mgmt_event,
43
+ struct net_if *iface)
44
+ {
45
+ if (mgmt_event == NET_EVENT_IF_UP) {
46
+ // printk("Interface %p is up\n", iface);
47
+ } else {
48
+ // printk("Interface %p is down\n", iface);
49
+ }
50
+ }
51
+
52
+ static void addr_handler (struct net_mgmt_event_callback *cb,
53
+ uint32_t mgmt_event,
54
+ struct net_if *iface)
55
+ {
56
+ int i = 0 ;
57
+
58
+ if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) {
59
+ return ;
60
+ }
61
+
62
+ // printk("Interface %p has IP\n", iface);
63
+
64
+ for (i = 0 ; i < NET_IF_MAX_IPV4_ADDR; i++) {
65
+ char buf[NET_IPV4_ADDR_LEN];
66
+
67
+ if (iface->config .ip .ipv4 ->unicast [i].ipv4 .addr_type !=
68
+ NET_ADDR_DHCP) {
69
+ continue ;
70
+ }
71
+
72
+ LOG_INF (" Address[%d]: %s" , net_if_get_by_iface (iface),
73
+ net_addr_ntop (AF_INET,
74
+ &iface->config .ip .ipv4 ->unicast [i].ipv4 .address .in_addr ,
75
+ buf, sizeof (buf)));
76
+ LOG_INF (" Subnet[%d]: %s" , net_if_get_by_iface (iface),
77
+ net_addr_ntop (AF_INET,
78
+ &iface->config .ip .ipv4 ->unicast [i].netmask ,
79
+ buf, sizeof (buf)));
80
+ LOG_INF (" Router[%d]: %s" , net_if_get_by_iface (iface),
81
+ net_addr_ntop (AF_INET,
82
+ &iface->config .ip .ipv4 ->gw ,
83
+ buf, sizeof (buf)));
84
+ LOG_INF (" Lease time[%d]: %u seconds" , net_if_get_by_iface (iface),
85
+ iface->config .dhcpv4 .lease_time );
86
+ }
87
+ }
88
+
89
+ static void option_handler (struct net_dhcpv4_option_callback *cb,
90
+ size_t length,
91
+ enum net_dhcpv4_msg_type msg_type,
92
+ struct net_if *iface)
93
+ {
94
+ char buf[NET_IPV4_ADDR_LEN];
95
+
96
+ LOG_INF (" DHCP Option %d: %s" , cb->option ,
97
+ net_addr_ntop (AF_INET, cb->data , buf, sizeof (buf)));
98
+ }
99
+
100
+ int dhcp ()
101
+ {
102
+ net_mgmt_init_event_callback (&mgmt_cb, addr_handler, NET_EVENT_IPV4_ADDR_ADD);
103
+ net_mgmt_add_event_callback (&mgmt_cb);
104
+
105
+ net_mgmt_init_event_callback (&mgmt_cb, link_handler, NET_EVENT_IF_UP | NET_EVENT_IF_DOWN);
106
+ net_mgmt_add_event_callback (&mgmt_cb);
107
+
108
+ net_dhcpv4_init_option_callback (&dhcp_cb, option_handler,
109
+ DHCP_OPTION_NTP, ntp_server,
110
+ sizeof (ntp_server));
111
+
112
+ net_dhcpv4_add_option_callback (&dhcp_cb);
113
+
114
+ net_dhcpv4_start (net_if_get_by_index (iface_index));
115
+
116
+ return 0 ;
117
+ }
118
+
119
+ public:
120
+ NetworkInterface (int iface_index) : iface_index(iface_index) {
121
+ }
122
+ ~NetworkInterface () {}
123
+ IPAddress localIP () {
124
+ return IPAddress (net_if_get_by_index (iface_index)->config .ip .ipv4 ->unicast [0 ].ipv4 .address .in_addr .s_addr );
125
+ }
126
+
127
+ IPAddress subnetMask () {
128
+ return IPAddress (net_if_get_by_index (iface_index)->config .ip .ipv4 ->unicast [0 ].netmask .s_addr );
129
+ }
130
+ IPAddress gatewayIP () {
131
+ return IPAddress (net_if_get_by_index (iface_index)->config .ip .ipv4 ->gw .s_addr );
132
+ }
133
+ IPAddress dnsServerIP () {
134
+ return arduino::INADDR_NONE;
135
+ }
136
+
137
+ IPAddress dnsIP (int n = 0 );
138
+
139
+ void setMACAddress (const uint8_t * mac);
140
+
141
+ bool begin () {
142
+ dhcp ();
143
+ // TODO: replace me with semaphore on the callback
144
+ while (net_if_get_by_index (iface_index)->config .ip .ipv4 ->unicast [0 ].ipv4 .address .in_addr .s_addr == 0 ) {
145
+ k_sleep (K_MSEC (100 ));
146
+ }
147
+ return 0 ;
148
+ }
149
+
150
+ // Manual functions
151
+ // net_if_ipv4_set_netmask_by_addr(iface, &addr4, &nm);
152
+ // net_if_ipv4_addr_add(iface, &addr4, NET_ADDR_MANUAL, 0);
153
+
154
+ #ifdef SPECIALIZE_FOR_ETHERNET
155
+ EthernetLinkStatus linkStatus () {
156
+ if (net_if_is_up (net_if_get_by_index (iface_index))) {
157
+ return LinkON;
158
+ } else {
159
+ return LinkOFF;
160
+ }
161
+ }
162
+
163
+ EthernetHardwareStatus hardwareStatus () {
164
+ const struct device *const dev = DEVICE_DT_GET (DT_COMPAT_GET_ANY_STATUS_OKAY (ethernet_phy));
165
+ if (device_is_ready (dev)) {
166
+ return EthernetOk;
167
+ } else {
168
+ return EthernetNoHardware;
169
+ }
170
+ }
171
+ #endif
172
+ };
0 commit comments