-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathethernet.cpp
118 lines (99 loc) · 2.34 KB
/
ethernet.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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
#include "ethernet_api.h"
#include "ethernetext_api.h"
#include <kernel.h>
#include "kernel_cfg.h"
#include "mbed.h"
#include "arduino_app.h"
#include "ethernet.h"
#include "ip.h"
#include "arp.h"
#include "util.h"
#include "netconf.h"
#include "protohdr.h"
static void ethrcv_callback(){
isig_sem(ETHERRECV_SEM);
}
void ethernet_initialize(){
//lwipドライバ(rza1_emac.c)を参考にした
ethernet_cfg_t ethcfg;
ethcfg.int_priority = 6;
ethcfg.recv_cb = ðrcv_callback;
ethcfg.ether_mac = NULL;
ethernetext_init(ðcfg);
ethernet_set_link(-1,0);
ethernet_address((char *)MACADDR);
}
static int recvskip_counter = 0;
void etherrecv_task(intptr_t exinf) {
wait(1);
while(true){
twai_sem(ETHERRECV_SEM, 10);
for(int i=0; i<16; i++){
wai_sem(ETHERIO_SEM);
uint32_t size = ethernet_receive();
if(size > sizeof(ether_hdr)){
char *buf = new char[size];
ethernet_read(buf, size);
sig_sem(ETHERIO_SEM);
if(ETHER_RECV_SKIP >= 0 && recvskip_counter >= ETHER_RECV_SKIP){
recvskip_counter = 0;
delete [] buf;
LOG("rejected");
continue;
}
recvskip_counter++;
ether_hdr *ehdr = (ether_hdr*)buf;
if(memcmp(ehdr->ether_dhost, MACADDR, ETHER_ADDR_LEN)!=0 &&
memcmp(ehdr->ether_dhost, ETHERBROADCAST, ETHER_ADDR_LEN)!=0){
delete [] buf; continue;
}
ether_flame *flm = new ether_flame;
flm->size = size;
flm->buf = buf;
switch(ntoh16(ehdr->ether_type)){
case ETHERTYPE_IP:
ip_process(flm, (ip_hdr*)(ehdr+1));
break;
case ETHERTYPE_ARP:
arp_process(flm, (ether_arp*)(ehdr+1));
break;
default:
delete flm;
break;
}
}else{
sig_sem(ETHERIO_SEM);
}
}
}
}
static int sendskip_counter = 0;
void ethernet_send(ether_flame *flm){
wai_sem(ETHERIO_SEM);
if(ETHER_SEND_SKIP >= 0 && sendskip_counter >= ETHER_SEND_SKIP){
sendskip_counter = 0;
sig_sem(ETHERIO_SEM);
return;
}
sendskip_counter++;
ethernet_write(flm->buf, flm->size);
ethernet_send();
sig_sem(ETHERIO_SEM);
return;
}
void ethernet_send(hdrstack *flm){
wai_sem(ETHERIO_SEM);
if(ETHER_SEND_SKIP >= 0 && sendskip_counter >= ETHER_SEND_SKIP){
sendskip_counter = 0;
sig_sem(ETHERIO_SEM);
return;
}
sendskip_counter++;
while(flm!=NULL){
ethernet_write(flm->buf, flm->size);
flm=flm->next;
}
ethernet_send();
sig_sem(ETHERIO_SEM);
return;
}