Skip to content

Commit 9fdb174

Browse files
committed
SocketWrapper: initial: add NetworkInterface class
1 parent 4d6dc58 commit 9fdb174

File tree

4 files changed

+183
-0
lines changed

4 files changed

+183
-0
lines changed

libraries/SocketWrapper/Ethernet.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "Ethernet.h"
2+
3+
NetworkInterface Ethernet(1);

libraries/SocketWrapper/Ethernet.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#define SPECIALIZE_FOR_ETHERNET
2+
#include "SocketHelpers.h"
3+
4+
extern NetworkInterface Ethernet;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include "SocketHelpers.h"
2+
3+
struct net_mgmt_event_callback NetworkInterface::mgmt_cb;
4+
struct net_dhcpv4_option_callback NetworkInterface::dhcp_cb;
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
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

Comments
 (0)