Newer
Older
#include <mutek/startup.h>
#include <device/resources.h>
#include <device/device.h>
#include <device/driver.h>
#include <device/irq.h>
#include <hexo/endian.h>
#include <device/class/gpio.h>
#include <device/class/net.h>
#include <net/layer.h>
#include <net/layer/ethernet.h>
#include <inet/layer/ipv4.h>
#include <inet/layer/icmp.h>
#include <inet/protocol/ip.h>
#include <net/scheduler.h>
#define MTU 128
struct app_s
{
struct device_net_s net;
struct net_scheduler_s scheduler;
struct buffer_pool_s packet_pool;
struct net_layer_s *eth;
struct net_layer_s *ipv4;
struct net_layer_s *icmp;
};
static
void eth_link_changed(void *delegate, struct net_layer_s *layer, bool_t connected)
struct app_s *app = delegate;
printk("Ethernet link now %s\n", connected ? "up" : "down");
}
static
void eth_destroyed(void *delegate, struct net_layer_s *layer)
{
struct app_s *app = delegate;
assert(app->eth == layer);
app->eth = NULL;
static
void ipv4_destroyed(void *delegate, struct net_layer_s *layer)
struct app_s *app = delegate;
printk("%s\n", __FUNCTION__);
assert(app->ipv4 == layer);
app->ipv4 = NULL;
static
void icmp_destroyed(void *delegate, struct net_layer_s *layer)
struct app_s *app = delegate;
printk("%s\n", __FUNCTION__);
assert(app->icmp == layer);
app->icmp = NULL;
static
SLAB_GROW(packet_pool_grow)
return 5;
}
static const struct net_ethernet_delegate_vtable_s eth_delegate_vtable = {
.base.release = eth_destroyed,
.link_changed = eth_link_changed,
};
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
static const struct net_layer_delegate_vtable_s ipv4_delegate_vtable = {
.release = ipv4_destroyed,
};
static const struct net_layer_delegate_vtable_s icmp_delegate_vtable = {
.release = icmp_destroyed,
};
void app_start()
{
error_t err;
struct app_s *app;
app = mem_alloc(sizeof(*app), mem_scope_sys);
if (!app) {
printk("Failed to create app context\n");
return;
}
err = device_get_accessor_by_path(&app->net.base, NULL, "eth*", DRIVER_CLASS_NET);
if (err) {
printk("Failed to get Ethernet device\n");
return;
}
buffer_pool_init(&app->packet_pool, MTU, packet_pool_grow, mem_scope_sys);
err = net_scheduler_init(&app->scheduler, &app->packet_pool, "timer* rtc*");
if (err) {
printk("Error while initializing net scheduler: %d\n", err);
return;
}
err = DEVICE_OP(&app->net, layer_create, &app->scheduler,
NET_LAYER_ETHERNET, NULL,
app, ð_delegate_vtable.base,
&app->eth);
if (err) {
printk("Error while creating Ethernet layer: %d\n", err);
return;
}
err = inet_ipv4_create(&app->scheduler, app, &ipv4_delegate_vtable, &app->ipv4);
if (err) {
printk("Error while creating ipv4 layer: %d\n", err);
return;
}
err = net_layer_bind(app->eth, NULL, app->ipv4);
if (err) {
printk("Unable to bind ipv4 layer above ethernet: %d\n", err);
return;
}
net_layer_refdec(app->ipv4);
err = inet_icmp_create(&app->scheduler, app, &icmp_delegate_vtable, &app->icmp);
if (err) {
printk("Error while creating icmp layer: %d\n", err);
return;
}
err = net_layer_bind(app->ipv4, (const uint8_t[]){ INET_IP_PROTO_ICMP }, app->icmp);
if (err) {
printk("Unable to bind icmp layer above ethernet: %d\n", err);
return;
}
net_layer_refdec(app->icmp);