summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2018-01-16 23:43:07 +0100
committerUros Majstorovic <majstor@majstor.org>2018-01-16 23:43:07 +0100
commit01c3e3af2394f863323b846fa304ff7e0a30e9df (patch)
tree84b499e6ece88e637ed86bbdd87333613e2433c5
parent0d0e9facfcea3cf96da3b63285865182fdd5477e (diff)
eos support
-rw-r--r--code/ecp/Makefile2
-rw-r--r--code/ecp/Makefile.fe310 (renamed from code/Makefile.fe310)6
-rw-r--r--code/ecp/Makefile.posix (renamed from code/Makefile.posix)0
-rw-r--r--code/ecp/config_fe310.h (renamed from code/config_fe310.h)0
-rw-r--r--code/ecp/config_posix.h (renamed from code/config_posix.h)0
-rw-r--r--code/ecp/core.c92
-rw-r--r--code/ecp/core.h25
-rw-r--r--code/ecp/crypto/Makefile2
-rw-r--r--code/ecp/crypto/chacha/Makefile2
-rw-r--r--code/ecp/crypto/compat/Makefile2
-rw-r--r--code/ecp/crypto/curve25519/Makefile2
-rw-r--r--code/ecp/crypto/poly1305/Makefile2
-rw-r--r--code/ecp/crypto/sha/Makefile2
-rw-r--r--code/ecp/crypto/test/Makefile2
-rw-r--r--code/ecp/fe310/Makefile4
-rw-r--r--code/ecp/fe310/time.c9
-rw-r--r--code/ecp/fe310/transport.c46
-rw-r--r--code/ecp/htable/Makefile2
-rw-r--r--code/ecp/posix/Makefile2
-rw-r--r--code/ecp/posix/transport.c8
-rw-r--r--code/ecp/rbuf.c4
-rw-r--r--code/ecp/rbuf.h8
-rw-r--r--code/ecp/rbuf_recv.c55
-rw-r--r--code/ecp/rbuf_send.c34
-rw-r--r--code/ecp/timer.c1
-rw-r--r--code/ecp/vconn/Makefile2
-rw-r--r--code/ecp/vconn/vconn.c16
-rw-r--r--code/esp32/Makefile9
-rw-r--r--code/esp32/components/eos/component.mk0
-rw-r--r--code/esp32/components/eos/fe310.c180
-rw-r--r--code/esp32/components/eos/include/eos.h2
-rw-r--r--code/esp32/components/eos/include/fe310.h18
-rw-r--r--code/esp32/components/eos/include/msgq.h20
-rw-r--r--code/esp32/components/eos/include/transport.h13
-rw-r--r--code/esp32/components/eos/msgq.c39
-rwxr-xr-xcode/esp32/components/eos/transport.c205
-rw-r--r--code/esp32/main/app_main.c26
-rw-r--r--code/esp32/main/component.mk8
-rw-r--r--code/fe310/eos/Makefile18
-rw-r--r--code/fe310/eos/ecp.c66
-rw-r--r--code/fe310/eos/ecp.h3
-rw-r--r--code/fe310/eos/eos.c17
-rw-r--r--code/fe310/eos/eos.h6
-rw-r--r--code/fe310/eos/event.c85
-rw-r--r--code/fe310/eos/event.h16
-rw-r--r--code/fe310/eos/interrupt.c53
-rw-r--r--code/fe310/eos/interrupt.h8
-rw-r--r--code/fe310/eos/msgq.c66
-rw-r--r--code/fe310/eos/msgq.h19
-rw-r--r--code/fe310/eos/net.c365
-rw-r--r--code/fe310/eos/net.h20
-rw-r--r--code/fe310/eos/spi.h32
-rw-r--r--code/fe310/eos/timer.c86
-rw-r--r--code/fe310/eos/timer.h7
-rwxr-xr-xcode/platform4
-rw-r--r--code/test/Makefile2
-rw-r--r--code/test/stress.c7
-rw-r--r--code/util/Makefile2
-rwxr-xr-xcode/util/keydump3
59 files changed, 1602 insertions, 133 deletions
diff --git a/code/ecp/Makefile b/code/ecp/Makefile
index 88d8c84..1b16f39 100644
--- a/code/ecp/Makefile
+++ b/code/ecp/Makefile
@@ -1,4 +1,4 @@
-include ../Makefile.platform
+include Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I.
obj = core.o timer.o $(obj_rbuf)
diff --git a/code/Makefile.fe310 b/code/ecp/Makefile.fe310
index aff2784..130566b 100644
--- a/code/Makefile.fe310
+++ b/code/ecp/Makefile.fe310
@@ -3,10 +3,10 @@ vconn=vconn
platform=fe310
rbuf_obj=
-FE310_HOME=/Users/majstor/src/sifive/freedom-e-sdk
-EOS_HOME=/Users/majstor/src/sifive/hello
+FE310_HOME=/opt/my/freedom-e-sdk
CC=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc
AR=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-ar
-CFLAGS_PL=-O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(EOS_HOME) -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1
+
+CFLAGS_PL=-O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1
# LDFLAGS_PL=-lm -pthread \ No newline at end of file
diff --git a/code/Makefile.posix b/code/ecp/Makefile.posix
index 2680875..2680875 100644
--- a/code/Makefile.posix
+++ b/code/ecp/Makefile.posix
diff --git a/code/config_fe310.h b/code/ecp/config_fe310.h
index fc95c26..fc95c26 100644
--- a/code/config_fe310.h
+++ b/code/ecp/config_fe310.h
diff --git a/code/config_posix.h b/code/ecp/config_posix.h
index ad67d8a..ad67d8a 100644
--- a/code/config_posix.h
+++ b/code/ecp/config_posix.h
diff --git a/code/ecp/core.c b/code/ecp/core.c
index f81bbc6..3f77c6f 100644
--- a/code/ecp/core.c
+++ b/code/ecp/core.c
@@ -544,7 +544,7 @@ static ssize_t _conn_send_kget(ECPConnection *conn, ECPTimerItem *ti) {
payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);
ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ);
- return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), ti);
+ return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);
}
int ecp_conn_init(ECPConnection *conn, ECPNode *node) {
@@ -687,7 +687,7 @@ static ssize_t _conn_send_open(ECPConnection *conn, ECPTimerItem *ti) {
ecp_pld_set_type(pld_buf, ECP_MTYPE_OPEN_REQ);
buf[0] = conn->type;
- return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(1, ECP_MTYPE_OPEN_REQ), ti);
+ return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(1, ECP_MTYPE_OPEN_REQ), 0, ti);
}
ssize_t ecp_conn_send_open(ECPConnection *conn) {
@@ -781,6 +781,7 @@ ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char m
unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn)];
unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_OPEN_REP, conn)];
unsigned char ctype = 0;
+
packet.buffer = pkt_buf;
packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn);
payload.buffer = pld_buf;
@@ -788,7 +789,7 @@ ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char m
ctype = msg[0];
ecp_pld_set_type(pld_buf, ECP_MTYPE_OPEN_REP);
- ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_OPEN_REP));
+ ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_OPEN_REP), 0);
return 1;
}
@@ -820,8 +821,10 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m
int rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1);
if (!rv && !is_open) {
ecp_conn_open_t *conn_open = ctx->handler[conn->type] ? ctx->handler[conn->type]->conn_open : NULL;
- ssize_t _rv = conn_open(conn);
- if (_rv < 0) rv = _rv;
+ if (conn_open) {
+ ssize_t _rv = conn_open(conn);
+ if (_rv < 0) rv = _rv;
+ }
}
if (rv) return rv;
@@ -844,7 +847,7 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m
ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REP);
int rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1);
if (rv) return rv;
- ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP));
+ ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0);
return 0;
}
@@ -875,7 +878,7 @@ ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char m
if (rv) return rv;
ecp_pld_set_type(pld_buf, ECP_MTYPE_KPUT_REP);
- ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KPUT_REP));
+ ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KPUT_REP), 0);
return ECP_ECDH_SIZE_KEY+1;
}
@@ -886,6 +889,7 @@ ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char m
ssize_t ecp_conn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
if (size < 0) return size;
if (b == NULL) return ECP_ERR;
+ if (b->packet->buffer == NULL) return ECP_ERR;
memcpy(b->packet->buffer, msg, size);
return ecp_pkt_handle(conn->sock, NULL, conn, b, size);
@@ -931,7 +935,7 @@ static ssize_t _conn_send_kput(ECPConnection *conn, ECPTimerItem *ti) {
rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1);
if (rv) return rv;
- return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ), ti);
+ return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ), 0, ti);
}
int ecp_conn_dhkey_new(ECPConnection *conn) {
@@ -1006,7 +1010,6 @@ int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned ch
ssize_t ecp_pack(ECPContext *ctx, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, unsigned char *payload, size_t pld_size) {
ssize_t rv;
- if (payload == NULL) return ECP_ERR;
if (pkt_size < ECP_SIZE_PKT_HDR) return ECP_ERR;
// ECP_SIZE_PROTO
@@ -1114,21 +1117,30 @@ ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_siz
}
ssize_t _ecp_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr) {
+ if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
+ if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
+
return ecp_conn_pack(conn, packet->buffer, packet->size, s_idx, c_idx, payload->buffer, pld_size, si, addr);
}
ssize_t _ecp_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) {
+ if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
+ if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
+
return ecp_pack_raw(sock, parent, packet->buffer, packet->size, s_idx, c_idx, public, shsec, nonce, seq, payload->buffer, pld_size, addr);
}
-ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *payload, size_t pld_size, unsigned char *packet, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq) {
+ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq) {
unsigned char s_idx;
unsigned char c_idx;
unsigned char l_idx = ECP_ECDH_IDX_INV;
+ unsigned char *payload = bufs->payload->buffer;
+ unsigned char *packet = bufs->packet->buffer;
ecp_aead_key_t shsec;
ecp_dh_public_t public;
ecp_dh_private_t private;
+ ECPContext *ctx = sock->ctx;
ECPConnection *conn = NULL;
ECPDHKey *key = NULL;
int rv = ECP_OK;
@@ -1198,7 +1210,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, uns
memset(&private, 0, sizeof(private));
}
- dec_size = sock->ctx->cr.aead_dec(payload, pld_size, packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, &shsec, packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY);
+ dec_size = sock->ctx->cr.aead_dec(payload, bufs->payload->size, packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, &shsec, packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY);
if (dec_size < ECP_SIZE_PLD_HDR+1) rv = ECP_ERR_DECRYPT;
if (rv) goto ecp_unpack_err;
@@ -1208,6 +1220,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, uns
(payload[2] << 8) | \
(payload[3]);
+ if (ctx->tr.buf_free && ((payload[ECP_SIZE_PLD_HDR] & ECP_MTYPE_MASK) < ECP_MAX_MTYPE_SYS)) ctx->tr.buf_free(bufs, ECP_SEND_FLAG_MORE);
if (conn == NULL) {
if (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_OPEN_REQ) {
is_new = 1;
@@ -1229,7 +1242,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, uns
rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1);
if (!rv) {
- ssize_t _rv = ecp_pld_send_raw(sock, parent, addr, &_packet, s_idx, c_idx, &public, &shsec, packet+ECP_SIZE_PKT_HDR, seq_p, &_payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP));
+ ssize_t _rv = ecp_pld_send_raw(sock, parent, addr, &_packet, s_idx, c_idx, &public, &shsec, packet+ECP_SIZE_PKT_HDR, seq_p, &_payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0);
if (_rv < 0) rv = _rv;
}
if (rv) return rv;
@@ -1327,13 +1340,13 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent,
ECPConnection *conn;
ecp_seq_t seq;
ssize_t rv = 0;
- ssize_t pld_size = ecp_unpack(sock, addr, parent, bufs->payload->buffer, bufs->payload->size, bufs->packet->buffer, pkt_size, &conn, &seq);
+ ssize_t pld_size = ecp_unpack(sock, addr, parent, bufs, pkt_size, &conn, &seq);
if (pld_size < 0) return pld_size;
if (conn) {
rv = 0;
#ifdef ECP_WITH_RBUF
- if (conn->rbuf.recv) rv = ecp_rbuf_recv_store(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR);
+ if (conn->rbuf.recv) rv = ecp_rbuf_recv_store(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs);
#endif
if (rv == 0) rv = ecp_msg_handle(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs);
@@ -1352,11 +1365,15 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent,
return ECP_SIZE_PKT_HDR+ECP_AEAD_SIZE_TAG+ECP_SIZE_PLD_HDR+rv;
}
-ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size) {
- ssize_t rv = sock->ctx->tr.send(&sock->sock, packet, pkt_size, addr);
+ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags) {
+ ssize_t rv = sock->ctx->tr.send(&sock->sock, packet, pkt_size, addr, flags);
if (rv < 0) return rv;
if (rv < ECP_MIN_PKT) return ECP_ERR_SEND;
+ if (flags & ECP_SEND_FLAG_REPLY) {
+ packet->buffer = NULL;
+ packet->size = 0;
+ }
return rv;
}
@@ -1536,7 +1553,7 @@ unsigned char *ecp_pld_get_buf(unsigned char *payload, unsigned char mtype) {
return payload + ECP_SIZE_PLD_HDR + 1 + ECP_SIZE_MT_FLAG(mtype);
}
-static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti, ECPSeqItem *si) {
+static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) {
ECPSocket *sock = conn->sock;
ECPContext *ctx = sock->ctx;
ECPNetAddr addr;
@@ -1545,25 +1562,25 @@ static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_
if (rv < 0) return rv;
#ifdef ECP_WITH_RBUF
- if (conn->rbuf.send) return ecp_rbuf_pkt_send(conn->rbuf.send, conn->sock, &addr, packet->buffer, rv, ti, si);
+ if (conn->rbuf.send) return ecp_rbuf_pkt_send(conn->rbuf.send, conn->sock, &addr, packet, rv, flags, ti, si);
#endif
if (ti) {
int _rv = ecp_timer_push(ti);
if (_rv) return _rv;
}
- return ecp_pkt_send(sock, &addr, packet->buffer, rv);
+ return ecp_pkt_send(sock, &addr, packet, rv, flags);
}
-ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size) {
- return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, NULL);
+ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags) {
+ return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, flags, NULL);
}
-ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti) {
- return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, ti);
+ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) {
+ return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, flags, ti);
}
-ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti) {
+ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) {
ECPSeqItem *_seq_item = NULL;
#ifdef ECP_WITH_RBUF
@@ -1576,10 +1593,10 @@ ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_
}
#endif
- return pld_send(conn, packet, s_idx, c_idx, payload, pld_size, ti, _seq_item);
+ return pld_send(conn, packet, s_idx, c_idx, payload, pld_size, flags, ti, _seq_item);
}
-ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size) {
+ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, unsigned char flags) {
ECPContext *ctx = sock->ctx;
ECPNetAddr _addr;
ssize_t rv;
@@ -1587,7 +1604,7 @@ ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *add
rv = ctx->pack_raw(sock, parent, packet, s_idx, c_idx, public, shsec, nonce, seq, payload, pld_size, &_addr);
if (rv < 0) return rv;
- return ecp_pkt_send(sock, parent ? &_addr : addr, packet->buffer, rv);
+ return ecp_pkt_send(sock, parent ? &_addr : addr, packet, rv, flags);
}
ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *content, size_t content_size) {
@@ -1641,7 +1658,7 @@ ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *conten
content += frag_size;
seq_item.seq = seq_start + i;
- ssize_t _rv = pld_send(conn, &packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(frag_size, mtype), NULL, &seq_item);
+ ssize_t _rv = pld_send(conn, &packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(frag_size, mtype), 0, NULL, &seq_item);
if (_rv < 0) return _rv;
rv += _rv;
@@ -1649,7 +1666,7 @@ ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *conten
} else {
ecp_pld_set_type(pld_buf, mtype);
memcpy(ecp_pld_get_buf(pld_buf, mtype), content, content_size);
- rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(content_size, mtype));
+ rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(content_size, mtype), 0);
}
return rv;
}
@@ -1669,17 +1686,14 @@ ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg
#endif
}
-static int recv_p(ECPSocket *sock, ECPNetAddr *addr, unsigned char *pkt_buf, size_t size) {
+static int recv_p(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t size) {
ECP2Buffer bufs;
- ECPBuffer packet;
ECPBuffer payload;
unsigned char pld_buf[ECP_MAX_PLD];
- bufs.packet = &packet;
+ bufs.packet = packet;
bufs.payload = &payload;
- packet.buffer = pkt_buf;
- packet.size = ECP_MAX_PKT;
payload.buffer = pld_buf;
payload.size = ECP_MAX_PLD;
@@ -1691,16 +1705,20 @@ static int recv_p(ECPSocket *sock, ECPNetAddr *addr, unsigned char *pkt_buf, siz
int ecp_receiver(ECPSocket *sock) {
ECPNetAddr addr;
+ ECPBuffer packet;
unsigned char pkt_buf[ECP_MAX_PKT];
ecp_cts_t next = 0;
-
+ ssize_t rv = 0;
if (sock->ctx->tr.recv == NULL) return ECP_ERR;
sock->running = 1;
while(sock->running) {
- ssize_t rv = sock->ctx->tr.recv(&sock->sock, pkt_buf, ECP_MAX_PKT, &addr, next ? next : sock->poll_timeout);
+ packet.buffer = pkt_buf;
+ packet.size = ECP_MAX_PKT;
+
+ rv = sock->ctx->tr.recv(&sock->sock, &packet, &addr, next ? next : sock->poll_timeout);
if (rv > 0) {
- int _rv = recv_p(sock, &addr, pkt_buf, rv);
+ int _rv = recv_p(sock, &addr, &packet, rv);
DPRINT(_rv, "ERR:recv_p - RV:%d\n", _rv);
}
next = ecp_timer_exe(sock);
diff --git a/code/ecp/core.h b/code/ecp/core.h
index ce81d9d..0248814 100644
--- a/code/ecp/core.h
+++ b/code/ecp/core.h
@@ -78,10 +78,13 @@
#define ECP_CONN_FLAG_REG 0x01
#define ECP_CONN_FLAG_OPEN 0x02
+#define ECP_SEND_FLAG_REPLY 0x01
+#define ECP_SEND_FLAG_MORE 0x02
+
#define ecp_conn_is_reg(conn) ((conn->flags) & ECP_CONN_FLAG_REG)
#define ecp_conn_is_open(conn) ((conn->flags) & ECP_CONN_FLAG_OPEN)
-#include "../config.h"
+#include "config.h"
#include <sys/types.h>
#include <stddef.h>
@@ -184,16 +187,20 @@ typedef struct ECPTransportIface {
int init;
int (*open) (ECPNetSock *, void *addr);
void (*close) (ECPNetSock *);
- ssize_t (*send) (ECPNetSock *, void *, size_t, ECPNetAddr *);
- ssize_t (*recv) (ECPNetSock *, void *, size_t, ECPNetAddr *, int);
+ ssize_t (*send) (ECPNetSock *, struct ECPBuffer *packet, size_t, ECPNetAddr *, unsigned char);
+ ssize_t (*recv) (ECPNetSock *, struct ECPBuffer *packet, ECPNetAddr *, int);
int (*addr_eq) (ECPNetAddr *, ECPNetAddr *);
int (*addr_set) (ECPNetAddr *, void *addr);
+ void (*buf_free) (struct ECP2Buffer *, unsigned char);
+ void (*buf_flag_set) (struct ECP2Buffer *, unsigned char);
+ void (*buf_flag_clear) (struct ECP2Buffer *, unsigned char);
} ECPTransportIface;
typedef struct ECPTimeIface {
int init;
ecp_cts_t (*abstime_ms) (ecp_cts_t);
void (*sleep_ms) (ecp_cts_t);
+ void (*timer_set) (ecp_cts_t);
} ECPTimeIface;
#ifdef ECP_WITH_HTABLE
@@ -392,10 +399,10 @@ ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_siz
ssize_t _ecp_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr);
ssize_t _ecp_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr);
-ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *payload, size_t pld_size, unsigned char *packet, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq);
+ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq);
ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size);
-ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size);
+ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags);
int ecp_seq_item_init(ECPSeqItem *seq_item);
int ecp_frag_iter_init(ECPFragIter *iter, unsigned char *buffer, size_t buf_size);
@@ -413,10 +420,10 @@ int ecp_pld_set_pts(unsigned char *payload, unsigned char mtype, ecp_pts_t pts);
unsigned char *ecp_pld_get_buf(unsigned char *payload, unsigned char mtype);
unsigned char ecp_pld_get_type(unsigned char *payload);
-ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size);
-ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti);
-ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPTimerItem *ti);
-ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size);
+ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags);
+ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti);
+ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti);
+ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, unsigned char flags);
ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *content, size_t content_size);
ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_cts_t timeout);
diff --git a/code/ecp/crypto/Makefile b/code/ecp/crypto/Makefile
index a7145c7..797cb16 100644
--- a/code/ecp/crypto/Makefile
+++ b/code/ecp/crypto/Makefile
@@ -1,4 +1,4 @@
-include ../../Makefile.platform
+include ../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -Iinclude -I.. -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=
obj = e_chacha20poly1305.o crypto.o
diff --git a/code/ecp/crypto/chacha/Makefile b/code/ecp/crypto/chacha/Makefile
index 8a977ae..e64aac3 100644
--- a/code/ecp/crypto/chacha/Makefile
+++ b/code/ecp/crypto/chacha/Makefile
@@ -1,4 +1,4 @@
-include ../../../Makefile.platform
+include ../../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=
obj = chacha.o
diff --git a/code/ecp/crypto/compat/Makefile b/code/ecp/crypto/compat/Makefile
index 1afe391..9e96d9e 100644
--- a/code/ecp/crypto/compat/Makefile
+++ b/code/ecp/crypto/compat/Makefile
@@ -1,4 +1,4 @@
-include ../../../Makefile.platform
+include ../../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=
getentropy = getentropy_osx
diff --git a/code/ecp/crypto/curve25519/Makefile b/code/ecp/crypto/curve25519/Makefile
index c3f94f0..5799e0e 100644
--- a/code/ecp/crypto/curve25519/Makefile
+++ b/code/ecp/crypto/curve25519/Makefile
@@ -1,4 +1,4 @@
-include ../../../Makefile.platform
+include ../../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS= -DED25519
obj = curve25519.o curve25519-generic.o
diff --git a/code/ecp/crypto/poly1305/Makefile b/code/ecp/crypto/poly1305/Makefile
index 6bc384f..5751602 100644
--- a/code/ecp/crypto/poly1305/Makefile
+++ b/code/ecp/crypto/poly1305/Makefile
@@ -1,4 +1,4 @@
-include ../../../Makefile.platform
+include ../../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=
obj = poly1305.o
diff --git a/code/ecp/crypto/sha/Makefile b/code/ecp/crypto/sha/Makefile
index 1eb727f..4dc3f39 100644
--- a/code/ecp/crypto/sha/Makefile
+++ b/code/ecp/crypto/sha/Makefile
@@ -1,4 +1,4 @@
-include ../../../Makefile.platform
+include ../../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I../include -D__BEGIN_HIDDEN_DECLS= -D__END_HIDDEN_DECLS=
obj = sha1dgst.o sha1_one.o sha256.o sha512.o
diff --git a/code/ecp/crypto/test/Makefile b/code/ecp/crypto/test/Makefile
index 2a5fa3e..8ea463d 100644
--- a/code/ecp/crypto/test/Makefile
+++ b/code/ecp/crypto/test/Makefile
@@ -1,4 +1,4 @@
-include ../../../Makefile.platform
+include ../../Makefile.platform
CFLAGS=$(CFLAGS_PL) -I.. -I../include
LDFLAGS=$(LDFLAGS_PL)
diff --git a/code/ecp/fe310/Makefile b/code/ecp/fe310/Makefile
index 6dd42e2..1ccf322 100644
--- a/code/ecp/fe310/Makefile
+++ b/code/ecp/fe310/Makefile
@@ -1,5 +1,5 @@
-include ../../Makefile.platform
-CFLAGS=$(CFLAGS_PL) $(PIC) -I..
+include ../Makefile.platform
+CFLAGS=$(CFLAGS_PL) $(PIC) -I.. -I../../fe310
obj_tr = transport.o
obj_tm = time.o
diff --git a/code/ecp/fe310/time.c b/code/ecp/fe310/time.c
index 2ff98cb..4b8b2a7 100644
--- a/code/ecp/fe310/time.c
+++ b/code/ecp/fe310/time.c
@@ -1,5 +1,7 @@
#include <core.h>
+#include <eos/timer.h>
+
#include "encoding.h"
#include "platform.h"
@@ -10,9 +12,14 @@ static ecp_cts_t t_abstime_ms(ecp_cts_t msec) {
return now_ms + msec;
}
+static void t_timer_set(ecp_cts_t next) {
+ uint32_t tick = next * (uint64_t)RTC_FREQ / 1000;
+ eos_timer_set(tick, 1);
+}
+
int ecp_time_init(ECPTimeIface *t) {
t->init = 1;
t->abstime_ms = t_abstime_ms;
- t->sleep_ms = NULL;
+ t->timer_set = t_timer_set;
return 0;
}
diff --git a/code/ecp/fe310/transport.c b/code/ecp/fe310/transport.c
index b833ee3..9ff04ca 100644
--- a/code/ecp/fe310/transport.c
+++ b/code/ecp/fe310/transport.c
@@ -1,10 +1,10 @@
#include <stddef.h>
#include <string.h>
-#include <core.h>
+#include <eos/eos.h>
+#include <eos/net.h>
-#include "eos.h"
-#include "net.h"
+#include <core.h>
static int t_addr_eq(ECPNetAddr *addr1, ECPNetAddr *addr2) {
if (addr1->port != addr2->port) return 0;
@@ -20,27 +20,55 @@ static int t_open(int *sock, void *addr_s) {
static void t_close(int *sock) {
}
-static ssize_t t_send(int *sock, void *msg, size_t msg_size, ECPNetAddr *addr) {
- unsigned char *buf = msg;
+static ssize_t t_send(int *sock, ECPBuffer *packet, size_t msg_size, ECPNetAddr *addr, unsigned char flags) {
+ unsigned char *buf = NULL;
size_t addr_len = sizeof(addr->host) + sizeof(addr->port);
uint16_t buf_size = msg_size + addr_len;
+ unsigned char cmd = EOS_NET_CMD_PKT;
int rv;
- buf -= addr_len;
+ if (flags & ECP_SEND_FLAG_MORE) {
+ cmd |= EOS_NET_CMD_FLAG_ONEW;
+ }
+ if (flags & ECP_SEND_FLAG_REPLY) {
+ if (packet && packet->buffer) buf = packet->buffer-addr_len;
+ } else {
+ buf = eos_net_alloc();
+ }
+ if (buf == NULL) return ECP_ERR;
memcpy(buf, addr->host, sizeof(addr->host));
memcpy(buf+sizeof(addr->host), &addr->port, sizeof(addr->port));
- rv = eos_net_send(EOS_NET_CMD_PKT, buf, buf_size);
+ rv = eos_net_send(cmd, buf, buf_size);
if (rv) return ECP_ERR_SEND;
return msg_size;
}
+static void t_buf_free(ECP2Buffer *b, unsigned char flags) {
+ size_t addr_len = ECP_IPv4_ADDR_SIZE + sizeof(uint16_t);
+ if (b && b->packet && b->packet->buffer) eos_net_free(b->packet->buffer-addr_len, flags & ECP_SEND_FLAG_MORE);
+}
+
+static void t_buf_flag_set(ECP2Buffer *b, unsigned char flags) {
+ size_t addr_len = ECP_IPv4_ADDR_SIZE + sizeof(uint16_t);
+ if (flags & ECP_SEND_FLAG_MORE) {
+ if (b && b->packet && b->packet->buffer) eos_net_reserve(b->packet->buffer-addr_len);
+ }
+}
+
+static void t_buf_flag_clear(ECP2Buffer *b, unsigned char flags) {
+ if (flags & ECP_SEND_FLAG_MORE) {
+ eos_net_release(1);
+ }
+}
+
int ecp_transport_init(ECPTransportIface *t) {
t->init = 1;
t->open = t_open;
t->close = t_close;
t->send = t_send;
- t->recv = NULL;
t->addr_eq = t_addr_eq;
- t->addr_set = NULL;
+ t->buf_free = t_buf_free;
+ t->buf_flag_set = t_buf_flag_set;
+ t->buf_flag_clear = t_buf_flag_clear;
return ECP_OK;
}
diff --git a/code/ecp/htable/Makefile b/code/ecp/htable/Makefile
index eb73403..6f5b888 100644
--- a/code/ecp/htable/Makefile
+++ b/code/ecp/htable/Makefile
@@ -1,4 +1,4 @@
-include ../../Makefile.platform
+include ../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I.. -std=gnu89
obj = htable.o hashtable.o hashtable_itr.o
diff --git a/code/ecp/posix/Makefile b/code/ecp/posix/Makefile
index 6dd42e2..595b0b5 100644
--- a/code/ecp/posix/Makefile
+++ b/code/ecp/posix/Makefile
@@ -1,4 +1,4 @@
-include ../../Makefile.platform
+include ../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I..
obj_tr = transport.o
diff --git a/code/ecp/posix/transport.c b/code/ecp/posix/transport.c
index df8e0f5..bdd166a 100644
--- a/code/ecp/posix/transport.c
+++ b/code/ecp/posix/transport.c
@@ -71,17 +71,17 @@ static void t_close(int *sock) {
close(*sock);
}
-static ssize_t t_send(int *sock, void *msg, size_t msg_size, ECPNetAddr *addr) {
+static ssize_t t_send(int *sock, ECPBuffer *packet, size_t msg_size, ECPNetAddr *addr, unsigned char flags) {
struct sockaddr_in servaddr;
memset((void *)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = addr->port;
memcpy((void *)&servaddr.sin_addr, addr->host, sizeof(addr->host));
- return sendto(*sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
+ return sendto(*sock, packet->buffer, msg_size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
}
-static ssize_t t_recv(int *sock, void *msg, size_t msg_size, ECPNetAddr *addr, int timeout) {
+static ssize_t t_recv(int *sock, ECPBuffer *packet, ECPNetAddr *addr, int timeout) {
struct sockaddr_in servaddr;
socklen_t addrlen = sizeof(servaddr);
struct pollfd fds[] = {
@@ -91,7 +91,7 @@ static ssize_t t_recv(int *sock, void *msg, size_t msg_size, ECPNetAddr *addr, i
int rv = poll(fds, 1, timeout);
memset((void *)&servaddr, 0, sizeof(servaddr));
if (rv == 1) {
- ssize_t recvlen = recvfrom(*sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, &addrlen);
+ ssize_t recvlen = recvfrom(*sock, packet->buffer, packet->size, 0, (struct sockaddr *)&servaddr, &addrlen);
if (recvlen < 0) return recvlen;
if (recvlen < ECP_MIN_PKT) return ECP_ERR_RECV;
diff --git a/code/ecp/rbuf.c b/code/ecp/rbuf.c
index b5f66a9..d24ac23 100644
--- a/code/ecp/rbuf.c
+++ b/code/ecp/rbuf.c
@@ -44,7 +44,7 @@ ssize_t ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned ch
return msg_size;
}
-ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, ecp_seq_t seq) {
+ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_seq_t seq) {
ECPSocket *sock = conn->sock;
ECPContext *ctx = sock->ctx;
ECPNetAddr addr;
@@ -61,7 +61,7 @@ ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *pay
rv = ctx->pack(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, &seq_item, &addr);
if (rv < 0) return rv;
- rv = ecp_pkt_send(sock, &addr, packet->buffer, rv);
+ rv = ecp_pkt_send(sock, &addr, packet, rv, flags);
if (rv < 0) return rv;
return rv;
diff --git a/code/ecp/rbuf.h b/code/ecp/rbuf.h
index 145234f..c4ea08e 100644
--- a/code/ecp/rbuf.h
+++ b/code/ecp/rbuf.h
@@ -51,8 +51,8 @@ typedef struct ECPRBTimer {
typedef struct ECPRBRecv {
unsigned char flags;
- unsigned char flush;
unsigned char timer_pts;
+ unsigned char ack_do;
unsigned short hole_max;
unsigned short ack_rate;
ecp_pts_t deliver_delay;
@@ -94,7 +94,7 @@ int ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq);
int ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq);
ssize_t ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned char *msg, size_t msg_size, unsigned char test_flags, unsigned char set_flags);
-ssize_t ecp_rbuf_pld_send(struct ECPConnection *conn, struct ECPBuffer *packet, struct ECPBuffer *payload, size_t pld_size, ecp_seq_t seq);
+ssize_t ecp_rbuf_pld_send(struct ECPConnection *conn, struct ECPBuffer *packet, struct ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_seq_t seq);
int ecp_rbuf_create(struct ECPConnection *conn, ECPRBSend *buf_s, ECPRBMessage *msg_s, unsigned int msg_s_size, ECPRBRecv *buf_r, ECPRBMessage *msg_r, unsigned int msg_r_size);
void ecp_rbuf_destroy(struct ECPConnection *conn);
@@ -104,13 +104,13 @@ void ecp_rbuf_recv_destroy(struct ECPConnection *conn);
int ecp_rbuf_recv_set_hole(struct ECPConnection *conn, unsigned short hole_max);
int ecp_rbuf_recv_set_delay(struct ECPConnection *conn, ecp_pts_t delay);
int ecp_rbuf_recv_start(struct ECPConnection *conn, ecp_seq_t seq);
-ssize_t ecp_rbuf_recv_store(struct ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size);
+ssize_t ecp_rbuf_recv_store(struct ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b);
int ecp_rbuf_send_create(struct ECPConnection *conn, ECPRBSend *buf, ECPRBMessage *msg, unsigned int msg_size);
void ecp_rbuf_send_destroy(struct ECPConnection *conn);
int ecp_rbuf_send_start(struct ECPConnection *conn);
int ecp_rbuf_pkt_prep(ECPRBSend *buf, struct ECPSeqItem *si, unsigned char mtype);
-ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, struct ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, ECPTimerItem *ti, struct ECPSeqItem *si);
+ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, struct ECPSocket *sock, ECPNetAddr *addr, struct ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, struct ECPSeqItem *si);
ssize_t ecp_rbuf_handle_ack(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);
ssize_t ecp_rbuf_handle_flush(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);
diff --git a/code/ecp/rbuf_recv.c b/code/ecp/rbuf_recv.c
index 44b5113..c262f1d 100644
--- a/code/ecp/rbuf_recv.c
+++ b/code/ecp/rbuf_recv.c
@@ -5,7 +5,7 @@
#define ACK_RATE 8
#define ACK_MASK_FIRST ((ecp_ack_t)1 << (ECP_SIZE_ACKB - 1))
-static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size) {
+static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
ECPRBRecv *buf = conn->rbuf.recv;
unsigned char flags = ECP_RBUF_FLAG_IN_RBUF;
unsigned char mtype = ecp_msg_get_type(msg) & ECP_MTYPE_MASK;
@@ -29,12 +29,12 @@ static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg,
if (rv < 0) return rv;
if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) buf->rbuf.seq_max = seq;
- if (flags & ECP_RBUF_FLAG_SYS) ecp_msg_handle(conn, seq, msg, msg_size, NULL);
+ if (flags & ECP_RBUF_FLAG_SYS) ecp_msg_handle(conn, seq, msg, msg_size, b);
return rv;
}
-static void msg_flush(ECPConnection *conn) {
+static void msg_flush(ECPConnection *conn, ECP2Buffer *b) {
ECPRBRecv *buf = conn->rbuf.recv;
#ifdef ECP_WITH_MSGQ
@@ -101,7 +101,7 @@ static void msg_flush(ECPConnection *conn) {
buf->rbuf.msg[idx].flags |= ECP_RBUF_FLAG_IN_MSGQ;
#endif
} else {
- ecp_msg_handle(conn, seq, buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, NULL);
+ ecp_msg_handle(conn, seq, buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, b);
}
}
buf->rbuf.msg[idx].flags &= ~ECP_RBUF_FLAG_IN_RBUF;
@@ -148,10 +148,11 @@ static int ack_send(ECPConnection *conn) {
buf_[6] = (buf->ack_map & 0x0000FF00) >> 8;
buf_[7] = (buf->ack_map & 0x000000FF);
- rv = ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK), 0);
+ rv = ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK), 0, 0);
if (rv < 0) return rv;
buf->ack_pkt = 0;
+ buf->ack_do = 0;
return ECP_OK;
}
@@ -170,7 +171,7 @@ static int ack_shift(ECPRBRecv *buf) {
if (in_rbuf && (buf->ack_map == ECP_ACK_FULL)) continue;
buf->ack_map = buf->ack_map << 1;
- if (in_rbuf & ECP_RBUF_FLAG_IN_RBUF) {
+ if (in_rbuf) {
buf->ack_map |= 1;
} else if (!do_ack && ECP_SEQ_LTE(buf->seq_ack, buf->rbuf.seq_max - 2 * buf->hole_max)) {
do_ack = 1;
@@ -197,10 +198,12 @@ static int ack_shift(ECPRBRecv *buf) {
ssize_t ecp_rbuf_handle_flush(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
if (size < 0) return size;
+ ECPContext *ctx = conn->sock->ctx;
ECPRBRecv *buf = conn->rbuf.recv;
if (buf == NULL) return ECP_ERR;
- buf->flush = 1;
+ if (ctx->tr.buf_free) ctx->tr.buf_free(b, ECP_SEND_FLAG_MORE);
+ ack_send(conn);
return 0;
}
@@ -209,7 +212,7 @@ ssize_t ecp_rbuf_handle_flush_pts(ECPConnection *conn, ecp_seq_t seq, unsigned c
if (buf == NULL) return ECP_ERR;
buf->timer_pts = 0;
- msg_flush(conn);
+ msg_flush(conn, b);
return 0;
}
@@ -282,17 +285,20 @@ int ecp_rbuf_recv_start(ECPConnection *conn, ecp_seq_t seq) {
return ECP_OK;
}
-ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size) {
+ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
ECPRBRecv *buf = conn->rbuf.recv;
ecp_seq_t ack_pkt = 0;
ssize_t rv;
- int do_ack = 0;
unsigned char mtype;
mtype = ecp_msg_get_type(msg) & ECP_MTYPE_MASK;
- if ((mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) return ecp_msg_handle(conn, seq, msg, msg_size, NULL);
+ if ((mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) return ecp_msg_handle(conn, seq, msg, msg_size, b);
- if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) ack_pkt = seq - buf->rbuf.seq_max;
+ if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) {
+ ack_pkt = seq - buf->rbuf.seq_max;
+ buf->ack_pkt += ack_pkt;
+ if (buf->ack_pkt > buf->ack_rate) buf->ack_do = 1;
+ }
if (ECP_SEQ_LTE(seq, buf->seq_ack)) {
ecp_seq_t seq_offset = buf->seq_ack - seq;
if (seq_offset < ECP_SIZE_ACKB) {
@@ -301,9 +307,9 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m
if (ack_mask & buf->ack_map) return ECP_ERR_RBUF_DUP;
buf->ack_map |= ack_mask;
- do_ack = ack_shift(buf);
+ buf->ack_do = buf->ack_do || ack_shift(buf);
- rv = msg_store(conn, seq, msg, msg_size);
+ rv = msg_store(conn, seq, msg, msg_size, b);
if (rv < 0) return rv;
} else {
return ECP_ERR_RBUF_DUP;
@@ -311,10 +317,10 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m
} else {
if ((buf->ack_map == ECP_ACK_FULL) && (seq == (ecp_seq_t)(buf->seq_ack + 1))) {
if ((buf->flags & ECP_RBUF_FLAG_MSGQ) || buf->deliver_delay) {
- rv = msg_store(conn, seq, msg, msg_size);
+ rv = msg_store(conn, seq, msg, msg_size, b);
if (rv < 0) return rv;
} else {
- ecp_msg_handle(conn, seq, msg, msg_size, NULL);
+ ecp_msg_handle(conn, seq, msg, msg_size, b);
rv = msg_size;
buf->rbuf.seq_max++;
buf->rbuf.seq_start++;
@@ -322,23 +328,14 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m
}
buf->seq_ack++;
} else {
- rv = msg_store(conn, seq, msg, msg_size);
+ rv = msg_store(conn, seq, msg, msg_size, b);
if (rv < 0) return rv;
- do_ack = ack_shift(buf);
+ buf->ack_do = buf->ack_do || ack_shift(buf);
}
}
- msg_flush(conn);
- if (buf->flush) {
- buf->flush = 0;
- do_ack = 1;
- }
- if (ack_pkt && !do_ack) {
- buf->ack_pkt += ack_pkt;
- // should send acks more aggresively when reliable and ack_map is not full (rate ~ PPS * RTT)
- if (buf->ack_pkt > buf->ack_rate) do_ack = 1;
- }
- if (do_ack) {
+ msg_flush(conn, b);
+ if (!(mtype < ECP_MAX_MTYPE_SYS) && buf->ack_do) {
int _rv = ack_send(conn);
if (_rv) return _rv;
}
diff --git a/code/ecp/rbuf_send.c b/code/ecp/rbuf_send.c
index f913e7e..61b29af 100644
--- a/code/ecp/rbuf_send.c
+++ b/code/ecp/rbuf_send.c
@@ -25,7 +25,7 @@ static ssize_t flush_send(ECPConnection *conn, ECPTimerItem *ti) {
rv = ecp_timer_push(&_ti);
if (rv) return rv;
}
- return ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_RBFLUSH), 0);
+ return ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_RBFLUSH), 0, 0);
}
static void cc_flush(ECPConnection *conn) {
@@ -65,8 +65,12 @@ static void cc_flush(ECPConnection *conn) {
#endif
for (i=0; i<pkt_to_send; i++) {
+ ECPBuffer packet;
+
if (rbuf->msg[_idx].idx_t != -1) ecp_timer_push(&ti[rbuf->msg[_idx].idx_t]);
- ecp_pkt_send(conn->sock, &conn->node.addr, rbuf->msg[_idx].msg, rbuf->msg[_idx].size);
+ packet.buffer = rbuf->msg[_idx].msg;
+ packet.size = rbuf->msg[_idx].size;
+ ecp_pkt_send(conn->sock, &conn->node.addr, &packet, rbuf->msg[_idx].size, 0);
_idx = ECP_RBUF_IDX_MASK(_idx + 1, rbuf->msg_size);
}
@@ -82,6 +86,7 @@ static void cc_flush(ECPConnection *conn) {
ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
ECPRBSend *buf;
+ ECPContext *ctx = conn->sock->ctx;
ssize_t rsize = sizeof(ecp_seq_t)+sizeof(ecp_ack_t);
ecp_seq_t seq_ack = 0;
ecp_ack_t ack_map = 0;
@@ -105,6 +110,8 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt
(msg[6] << 8) | \
(msg[7]);
+ if (ctx->tr.buf_flag_set) ctx->tr.buf_flag_set(b, ECP_SEND_FLAG_MORE);
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&buf->mutex);
#endif
@@ -146,9 +153,12 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt
payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_NOP, conn);
ecp_pld_set_type(pld_buf, ECP_MTYPE_NOP);
- ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_NOP), seq_ack + i);
+ ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_NOP), 0, seq_ack + i);
} else {
- ecp_pkt_send(conn->sock, &conn->node.addr, rbuf->msg[_idx].msg, rbuf->msg[_idx].size);
+ ECPBuffer packet;
+ packet.buffer = rbuf->msg[_idx].msg;
+ packet.size = rbuf->msg[_idx].size;
+ ecp_pkt_send(conn->sock, &conn->node.addr, &packet, rbuf->msg[_idx].size, 0);
}
if (!nack_first) {
nack_first = 1;
@@ -188,12 +198,14 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt
pthread_mutex_unlock(&buf->mutex);
#endif
- if (rv) return rv;
-
- if (do_flush) {
+ if (!rv && do_flush) {
ssize_t _rv = flush_send(conn, NULL);
- if (_rv < 0) return _rv;
+ if (_rv < 0) rv = _rv;
}
+
+ if (ctx->tr.buf_flag_clear) ctx->tr.buf_flag_clear(b, ECP_SEND_FLAG_MORE);
+
+ if (rv) return rv;
return rsize;
}
@@ -308,7 +320,7 @@ int ecp_rbuf_pkt_prep(ECPRBSend *buf, ECPSeqItem *si, unsigned char mtype) {
return ECP_OK;
}
-ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, ECPTimerItem *ti, ECPSeqItem *si) {
+ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) {
int do_send = 1;
ssize_t rv = 0;
@@ -320,7 +332,7 @@ ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, uns
if (mtype < ECP_MAX_MTYPE_SYS) flags |= ECP_RBUF_FLAG_SYS;
- rv = ecp_rbuf_msg_store(&buf->rbuf, seq, idx, packet, pkt_size, 0, flags);
+ rv = ecp_rbuf_msg_store(&buf->rbuf, seq, idx, packet->buffer, pkt_size, 0, flags);
if (rv < 0) return rv;
if (buf->flags & ECP_RBUF_FLAG_CCONTROL) {
@@ -369,7 +381,7 @@ ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, uns
int _rv = ecp_timer_push(ti);
if (_rv) return _rv;
}
- rv = ecp_pkt_send(sock, addr, packet, pkt_size);
+ rv = ecp_pkt_send(sock, addr, packet, pkt_size, flags);
}
return rv;
}
diff --git a/code/ecp/timer.c b/code/ecp/timer.c
index 691f75c..16a6ad0 100644
--- a/code/ecp/timer.c
+++ b/code/ecp/timer.c
@@ -58,6 +58,7 @@ int ecp_timer_push(ECPTimerItem *ti) {
if (!rv && !is_reg) rv = ECP_ERR_CLOSED;
if (!rv) {
+ if (ctx->tm.timer_set) ctx->tm.timer_set(ti->timeout);
for (i=timer->head; i>=0; i--) {
if (ECP_CTS_LTE(ti->abstime, timer->item[i].abstime)) {
if (i != timer->head) memmove(timer->item+i+2, timer->item+i+1, sizeof(ECPTimerItem) * (timer->head-i));
diff --git a/code/ecp/vconn/Makefile b/code/ecp/vconn/Makefile
index 613601c..d9d2e6f 100644
--- a/code/ecp/vconn/Makefile
+++ b/code/ecp/vconn/Makefile
@@ -1,4 +1,4 @@
-include ../../Makefile.platform
+include ../Makefile.platform
CFLAGS=$(CFLAGS_PL) $(PIC) -I..
obj = vconn.o
diff --git a/code/ecp/vconn/vconn.c b/code/ecp/vconn/vconn.c
index dadff0f..4023aa9 100644
--- a/code/ecp/vconn/vconn.c
+++ b/code/ecp/vconn/vconn.c
@@ -81,7 +81,7 @@ static ssize_t _vconn_send_open(ECPConnection *conn, ECPTimerItem *ti) {
payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);
ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ);
- return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), ti);
+ return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);
}
static ssize_t vconn_open(ECPConnection *conn) {
@@ -198,7 +198,7 @@ static ssize_t vconn_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c
payload.size = b->payload->size - (payload.buffer - b->payload->buffer);
ecp_pld_set_type(payload.buffer, ECP_MTYPE_EXEC);
- rv = ecp_pld_send(conn_out, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size);
+ rv = ecp_pld_send(conn_out, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size, ECP_SEND_FLAG_REPLY);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&conn_out->mutex);
@@ -286,7 +286,7 @@ static ssize_t _vlink_send_open(ECPConnection *conn, ECPTimerItem *ti) {
buf[0] = conn->type;
memcpy(buf+1, ctx->cr.dh_pub_get_buf(&sock->key_perma.public), ECP_ECDH_SIZE_KEY);
- return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ), ti);
+ return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ), 0, ti);
}
static ssize_t vlink_open(ECPConnection *conn) {
@@ -372,7 +372,7 @@ static ssize_t vlink_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c
payload.size = b->payload->size - (payload.buffer - b->payload->buffer);
ecp_pld_set_type(payload.buffer, ECP_MTYPE_EXEC);
- rv = ecp_pld_send(conn, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size);
+ rv = ecp_pld_send(conn, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size, ECP_SEND_FLAG_REPLY);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&conn->mutex);
@@ -422,6 +422,9 @@ static ssize_t vconn_set_msg(ECPConnection *conn, ECPBuffer *payload, unsigned c
static ssize_t vconn_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr) {
ECPContext *ctx = conn->sock->ctx;
+ if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
+ if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
+
if (conn->parent) {
unsigned char mtype = ecp_pld_get_type(payload->buffer);
ssize_t rv, hdr_size = vconn_set_msg(conn->parent, packet, mtype);
@@ -442,6 +445,9 @@ static ssize_t vconn_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char
static ssize_t vconn_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) {
ECPContext *ctx = sock->ctx;
+ if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
+ if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
+
if (parent) {
unsigned char mtype = ecp_pld_get_type(payload->buffer);
ssize_t rv, hdr_size = vconn_set_msg(parent, packet, mtype);
@@ -599,7 +605,7 @@ static ssize_t _vconn_send_kget(ECPConnection *conn, ECPTimerItem *ti) {
payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);
ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ);
- return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), ti);
+ return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);
}
int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnection vconn[], ECPNode vconn_node[], int size) {
diff --git a/code/esp32/Makefile b/code/esp32/Makefile
new file mode 100644
index 0000000..eb26385
--- /dev/null
+++ b/code/esp32/Makefile
@@ -0,0 +1,9 @@
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := eos-app
+
+include $(IDF_PATH)/make/project.mk
+
diff --git a/code/esp32/components/eos/component.mk b/code/esp32/components/eos/component.mk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/code/esp32/components/eos/component.mk
diff --git a/code/esp32/components/eos/fe310.c b/code/esp32/components/eos/fe310.c
new file mode 100644
index 0000000..6dceb51
--- /dev/null
+++ b/code/esp32/components/eos/fe310.c
@@ -0,0 +1,180 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <freertos/semphr.h>
+// #include <freertos/heap_regions.h>
+
+#include <esp_system.h>
+#include <esp_event.h>
+#include <esp_event_loop.h>
+#include <esp_log.h>
+#include <esp_err.h>
+#include <esp_heap_caps.h>
+#include <driver/spi_slave.h>
+
+#include "msgq.h"
+#include "transport.h"
+#include "fe310.h"
+
+static EOSMsgQ send_q;
+static EOSMsgItem send_q_array[EOS_FE310_SIZE_Q];
+
+#define SPI_GPIO_RTS 4
+#define SPI_GPIO_CTS 2
+#define SPI_GPIO_MOSI 23
+#define SPI_GPIO_MISO 19
+#define SPI_GPIO_SCLK 18
+#define SPI_GPIO_CS 5
+
+static SemaphoreHandle_t mutex;
+
+static const char *TAG = "EOS";
+
+static eos_fe310_fptr_t cmd_handler[EOS_FE310_MAX_CMD];
+
+static void bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ ESP_LOGI(TAG, "FE310 RECV: bad handler: %d", cmd);
+}
+
+static void worker(void *pvParameters) {
+ int repeat = 0;
+ esp_err_t ret;
+ unsigned char cmd = 0;
+ unsigned char *buffer;
+ uint16_t len;
+ unsigned char *buf_send = heap_caps_malloc(EOS_FE310_SIZE_BUF, MALLOC_CAP_DMA);
+ unsigned char *buf_recv = heap_caps_malloc(EOS_FE310_SIZE_BUF, MALLOC_CAP_DMA);
+
+ spi_slave_transaction_t t;
+ memset(&t, 0, sizeof(t));
+ t.length = EOS_FE310_SIZE_BUF*8;
+ t.tx_buffer = buf_send;
+ t.rx_buffer = buf_recv;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ for (;;) {
+ if (!repeat) {
+ eos_msgq_pop(&send_q, &cmd, &buffer, &len);
+ if (cmd) {
+ buf_send[0] = ((cmd << 3) | (len >> 8)) & 0xFF;
+ buf_send[1] = len & 0xFF;
+ if (buffer) memcpy(buf_send + 2, buffer, len);
+ } else {
+ WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_RTS));
+ buf_send[0] = 0;
+ buf_send[1] = 0;
+ }
+ }
+ memset(buf_recv, 0, EOS_FE310_SIZE_BUF);
+ ret = spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
+
+ repeat = 0;
+ if (buf_recv[0] != 0) {
+ xSemaphoreGive(mutex);
+
+ cmd = (buf_recv[0] >> 3);
+ len = ((buf_recv[0] & 0x07) << 8);
+ len |= buf_recv[1];
+ buffer = buf_recv + 2;
+ if (cmd & EOS_FE310_CMD_FLAG_ONEW) {
+ cmd &= ~EOS_FE310_CMD_FLAG_ONEW;
+ if (buf_send[0]) repeat = 1;
+ }
+ if (cmd < EOS_FE310_MAX_CMD) {
+ cmd_handler[cmd](cmd, buffer, len);
+ } else {
+ bad_handler(cmd, buffer, len);
+ }
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ } else {
+ ESP_LOGI(TAG, "FE310 RECV NULL");
+ }
+ // vTaskDelay(5000 / portTICK_PERIOD_MS);
+ }
+ xSemaphoreGive(mutex);
+}
+
+// Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high.
+static void _post_setup_cb(spi_slave_transaction_t *trans) {
+ xSemaphoreGive(mutex);
+ WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1 << SPI_GPIO_CTS));
+}
+
+// Called after transaction is sent/received. We use this to set the handshake line low.
+static void _post_trans_cb(spi_slave_transaction_t *trans) {
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_CTS));
+}
+
+void eos_fe310_init(void) {
+ esp_err_t ret;
+
+ // Configuration for the handshake lines
+ gpio_config_t io_conf;
+
+ io_conf.intr_type = GPIO_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_OUTPUT;
+ io_conf.pin_bit_mask = (1 << SPI_GPIO_CTS);
+ gpio_config(&io_conf);
+ WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_CTS));
+
+ io_conf.intr_type = GPIO_INTR_DISABLE;
+ io_conf.mode = GPIO_MODE_OUTPUT;
+ io_conf.pin_bit_mask = (1 << SPI_GPIO_RTS);
+ gpio_config(&io_conf);
+ WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1 << SPI_GPIO_RTS));
+
+ //Configuration for the SPI bus
+ spi_bus_config_t buscfg = {
+ .mosi_io_num = SPI_GPIO_MOSI,
+ .miso_io_num = SPI_GPIO_MISO,
+ .sclk_io_num = SPI_GPIO_SCLK
+ };
+
+ //Configuration for the SPI slave interface
+ spi_slave_interface_config_t slvcfg = {
+ .mode = 0,
+ .spics_io_num = SPI_GPIO_CS,
+ .queue_size = 2,
+ .flags = 0,
+ .post_setup_cb = _post_setup_cb,
+ .post_trans_cb = _post_trans_cb
+ };
+
+ //Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
+ gpio_set_pull_mode(SPI_GPIO_MOSI, GPIO_PULLUP_ONLY);
+ gpio_set_pull_mode(SPI_GPIO_SCLK, GPIO_PULLUP_ONLY);
+ gpio_set_pull_mode(SPI_GPIO_CS, GPIO_PULLUP_ONLY);
+
+ int i;
+ for (i=0; i<EOS_FE310_MAX_CMD; i++) {
+ cmd_handler[i] = bad_handler;
+ }
+
+ //Initialize SPI slave interface
+ ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1);
+ assert(ret==ESP_OK);
+
+ eos_msgq_init(&send_q, send_q_array, EOS_FE310_SIZE_Q);
+ mutex = xSemaphoreCreateMutex();
+ xTaskCreate(&worker, "fe310_receiver", 4096, NULL, 5, NULL);
+}
+
+int eos_fe310_send(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1 << SPI_GPIO_RTS));
+ int rv = eos_msgq_push(&send_q, cmd, buffer, len);
+ xSemaphoreGive(mutex);
+
+ return rv;
+}
+
+void eos_fe310_set_handler(unsigned char cmd, eos_fe310_fptr_t handler) {
+ cmd_handler[cmd] = handler;
+}
+
diff --git a/code/esp32/components/eos/include/eos.h b/code/esp32/components/eos/include/eos.h
new file mode 100644
index 0000000..a272ac8
--- /dev/null
+++ b/code/esp32/components/eos/include/eos.h
@@ -0,0 +1,2 @@
+#define EOS_OK 0
+#define EOS_ERR_Q_FULL -10 \ No newline at end of file
diff --git a/code/esp32/components/eos/include/fe310.h b/code/esp32/components/eos/include/fe310.h
new file mode 100644
index 0000000..f4bc787
--- /dev/null
+++ b/code/esp32/components/eos/include/fe310.h
@@ -0,0 +1,18 @@
+#include <stdint.h>
+
+#define EOS_FE310_CMD_FLAG_ONEW 0x10
+
+#define EOS_FE310_CMD_CONNECT 1
+#define EOS_FE310_CMD_DISCONNECT 2
+#define EOS_FE310_CMD_SCAN 3
+#define EOS_FE310_CMD_PKT 4
+
+#define EOS_FE310_MAX_CMD 8
+#define EOS_FE310_SIZE_Q 64
+#define EOS_FE310_SIZE_BUF 2048
+
+typedef void (*eos_fe310_fptr_t) (unsigned char, unsigned char *, uint16_t);
+
+void eos_fe310_init(void);
+int eos_fe310_send(unsigned char cmd, unsigned char *buffer, uint16_t len);
+void eos_fe310_set_handler(unsigned char cmd, eos_fe310_fptr_t handler);
diff --git a/code/esp32/components/eos/include/msgq.h b/code/esp32/components/eos/include/msgq.h
new file mode 100644
index 0000000..ebf54ce
--- /dev/null
+++ b/code/esp32/components/eos/include/msgq.h
@@ -0,0 +1,20 @@
+#include <stdint.h>
+
+#include "fe310.h"
+
+typedef struct EOSMsgItem {
+ unsigned char cmd;
+ unsigned char buffer[EOS_FE310_SIZE_BUF];
+ uint16_t len;
+} EOSMsgItem;
+
+typedef struct EOSMsgQ {
+ uint8_t idx_r;
+ uint8_t idx_w;
+ uint8_t size;
+ EOSMsgItem *array;
+} EOSMsgQ;
+
+void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size);
+int eos_msgq_push(EOSMsgQ *msgq, unsigned char cmd, unsigned char *buffer, uint16_t len);
+void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *cmd, unsigned char **buffer, uint16_t *len);
diff --git a/code/esp32/components/eos/include/transport.h b/code/esp32/components/eos/include/transport.h
new file mode 100644
index 0000000..9d76d1b
--- /dev/null
+++ b/code/esp32/components/eos/include/transport.h
@@ -0,0 +1,13 @@
+#include <stdint.h>
+
+#define EOS_IPv4_ADDR_SIZE 4
+
+typedef struct EOSNetAddr {
+ unsigned char host[EOS_IPv4_ADDR_SIZE];
+ uint16_t port;
+} EOSNetAddr;
+
+void eos_net_init(void);
+void eos_net_connect(char *ssid, char *password);
+void eos_net_disconnect(void);
+ssize_t eos_net_send(void *msg, size_t msg_size, EOSNetAddr *addr);
diff --git a/code/esp32/components/eos/msgq.c b/code/esp32/components/eos/msgq.c
new file mode 100644
index 0000000..ec89efe
--- /dev/null
+++ b/code/esp32/components/eos/msgq.c
@@ -0,0 +1,39 @@
+#include <stddef.h>
+#include <string.h>
+
+#include "eos.h"
+#include "msgq.h"
+
+#define EOS_MSGQ_IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1))
+
+void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) {
+ msgq->idx_r = 0;
+ msgq->idx_w = 0;
+ msgq->array = array;
+ msgq->size = size;
+}
+
+int eos_msgq_push(EOSMsgQ *msgq, unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ if (msgq->idx_w - msgq->idx_r == msgq->size) return EOS_ERR_Q_FULL;
+
+ uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_w, msgq->size);
+ msgq->array[idx].cmd = cmd;
+ memcpy(msgq->array[idx].buffer, buffer, len);
+ msgq->array[idx].len = len;
+ msgq->idx_w++;
+ return EOS_OK;
+}
+
+void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *cmd, unsigned char **buffer, uint16_t *len) {
+ if (msgq->idx_r == msgq->idx_w) {
+ *cmd = 0;
+ *buffer = NULL;
+ } else {
+ uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size);
+ *cmd = msgq->array[idx].cmd;
+ *buffer = msgq->array[idx].buffer;
+ *len = msgq->array[idx].len;
+ msgq->idx_r++;
+ }
+}
+
diff --git a/code/esp32/components/eos/transport.c b/code/esp32/components/eos/transport.c
new file mode 100755
index 0000000..162fe86
--- /dev/null
+++ b/code/esp32/components/eos/transport.c
@@ -0,0 +1,205 @@
+/*
+MIT License
+
+Copyright (c) 2017 Olof Astrand (Ebiroll)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include <string.h>
+#include <stdint.h>
+
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+
+#include <esp_system.h>
+#include <esp_event.h>
+#include <esp_event_loop.h>
+#include <esp_log.h>
+#include <esp_err.h>
+#include <esp_wifi.h>
+#include <nvs_flash.h>
+
+#include <lwip/sockets.h>
+#include <lwip/err.h>
+#include <lwip/sockets.h>
+#include <lwip/sys.h>
+#include <lwip/netdb.h>
+#include <lwip/dns.h>
+
+#include "eos.h"
+#include "fe310.h"
+#include "transport.h"
+
+static const char *TAG = "EOS";
+static int udp_sock = -1;
+static TaskHandle_t receiver_task;
+
+static int t_open(void) {
+ struct sockaddr_in _myaddr;
+
+ udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
+ if (udp_sock < 0) return udp_sock;
+
+ memset((char *)&_myaddr, 0, sizeof(_myaddr));
+ _myaddr.sin_family = AF_INET;
+ _myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ _myaddr.sin_port = htons(0);
+
+ int rv = bind(udp_sock, (struct sockaddr *)&_myaddr, sizeof(_myaddr));
+ if (rv < 0) {
+ close(udp_sock);
+ return rv;
+ }
+ return EOS_OK;
+}
+
+static void t_close(void) {
+ close(udp_sock);
+}
+
+static ssize_t t_send(void *msg, size_t msg_size, EOSNetAddr *addr) {
+ struct sockaddr_in servaddr;
+
+ memset((void *)&servaddr, 0, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = addr->port;
+ memcpy((void *)&servaddr.sin_addr, addr->host, sizeof(addr->host));
+ return sendto(udp_sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
+}
+
+static ssize_t t_recv(void *msg, size_t msg_size, EOSNetAddr *addr) {
+ struct sockaddr_in servaddr;
+ socklen_t addrlen = sizeof(servaddr);
+ memset((void *)&servaddr, 0, sizeof(servaddr));
+
+ ssize_t recvlen = recvfrom(udp_sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, &addrlen);
+ if (recvlen < 0) return recvlen;
+
+ if (addr) {
+ addr->port = servaddr.sin_port;
+ memcpy(addr->host, (void *)&servaddr.sin_addr, sizeof(addr->host));
+ }
+ return recvlen;
+}
+
+static void receiver(void *pvParameters) {
+ EOSNetAddr addr;
+ size_t addr_len = sizeof(addr.host) + sizeof(addr.port);
+ unsigned char buffer[2048];
+
+ for (;;) {
+ ssize_t rv = t_recv(buffer+addr_len, sizeof(buffer)-addr_len, &addr);
+ if (rv < 0) {
+ ESP_LOGI(TAG, "UDP RECV ERR:%d", rv);
+ continue;
+ }
+ memcpy(buffer, addr.host, sizeof(addr.host));
+ memcpy(buffer+sizeof(addr.host), &addr.port, sizeof(addr.port));
+ eos_fe310_send(EOS_FE310_CMD_PKT, buffer, rv+addr_len);
+ }
+}
+
+static void fe310_connect_cmd_handler(unsigned char cmd, unsigned char *buffer, uint16_t size) {
+ eos_net_connect((char *)buffer, (char *)(buffer+strlen((char *)buffer)+1));
+}
+
+static void fe310_packet_cmd_handler(unsigned char cmd, unsigned char *buffer, uint16_t size) {
+ EOSNetAddr addr;
+ size_t addr_len = sizeof(addr.host) + sizeof(addr.port);
+
+ memcpy(addr.host, buffer, sizeof(addr.host));
+ memcpy(&addr.port, buffer+sizeof(addr.host), sizeof(addr.port));
+ eos_net_send(buffer+addr_len, size-addr_len, &addr);
+}
+
+static esp_err_t esp32_wifi_event_handler(void *ctx, system_event_t *event) {
+ switch(event->event_id) {
+ case SYSTEM_EVENT_WIFI_READY:
+ break;
+
+ case SYSTEM_EVENT_AP_STACONNECTED:
+ break;
+
+ case SYSTEM_EVENT_AP_START:
+ break;
+
+ case SYSTEM_EVENT_SCAN_DONE:
+ break;
+
+ case SYSTEM_EVENT_STA_CONNECTED:
+ break;
+
+ case SYSTEM_EVENT_STA_DISCONNECTED:
+ ESP_LOGI(TAG, "DISCONNECT");
+ vTaskDelete(receiver_task);
+ t_close();
+ break;
+
+ case SYSTEM_EVENT_STA_GOT_IP:
+ ESP_LOGI(TAG, "********************************************");
+ ESP_LOGI(TAG, "* We are now connected to AP")
+ ESP_LOGI(TAG, "* - Our IP address is: " IPSTR, IP2STR(&event->event_info.got_ip.ip_info.ip));
+ ESP_LOGI(TAG, "********************************************");
+ t_open();
+ xTaskCreate(&receiver, "receiver", 4096, NULL, 5, &receiver_task);
+ eos_fe310_send(EOS_FE310_CMD_CONNECT, NULL, 0);
+ break;
+
+ default: // Ignore the other event types
+ break;
+ }
+
+ return ESP_OK;
+}
+
+void eos_net_init(void) {
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ wifi_config_t wifi_config;
+
+ memset(&wifi_config, 0, sizeof(wifi_config));
+ tcpip_adapter_init();
+ ESP_ERROR_CHECK( nvs_flash_init() );
+ ESP_ERROR_CHECK( esp_event_loop_init(esp32_wifi_event_handler, NULL) );
+ ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
+ ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
+ ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
+ ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
+ ESP_ERROR_CHECK( esp_wifi_start() );
+ eos_fe310_set_handler(EOS_FE310_CMD_CONNECT, fe310_connect_cmd_handler);
+ eos_fe310_set_handler(EOS_FE310_CMD_PKT, fe310_packet_cmd_handler);
+}
+
+void eos_net_connect(char *ssid, char *password) {
+ wifi_config_t wifi_config;
+
+ memset(&wifi_config, 0, sizeof(wifi_config));
+ strncpy((char *)wifi_config.sta.ssid, ssid, 31);
+ strncpy((char *)wifi_config.sta.password, password, 63);
+ ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
+ ESP_ERROR_CHECK( esp_wifi_connect() );
+}
+
+void eos_net_disconnect(void) {
+ ESP_ERROR_CHECK( esp_wifi_disconnect() );
+}
+
+ssize_t eos_net_send(void *msg, size_t msg_size, EOSNetAddr *addr) {
+ return t_send(msg, msg_size, addr);
+}
diff --git a/code/esp32/main/app_main.c b/code/esp32/main/app_main.c
new file mode 100644
index 0000000..1d3fa34
--- /dev/null
+++ b/code/esp32/main/app_main.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <freertos/semphr.h>
+
+#include <esp_system.h>
+#include <esp_event.h>
+#include <esp_event_loop.h>
+#include <esp_log.h>
+#include <esp_err.h>
+#include <driver/spi_slave.h>
+
+#include "fe310.h"
+#include "transport.h"
+
+// Main application
+void app_main() {
+ eos_fe310_init();
+ eos_net_init();
+}
+
+
diff --git a/code/esp32/main/component.mk b/code/esp32/main/component.mk
new file mode 100644
index 0000000..61f8990
--- /dev/null
+++ b/code/esp32/main/component.mk
@@ -0,0 +1,8 @@
+#
+# Main component makefile.
+#
+# This Makefile can be left empty. By default, it will take the sources in the
+# src/ directory, compile them and link them into lib(subdirectory_name).a
+# in the build directory. This behaviour is entirely configurable,
+# please read the ESP-IDF documents if you need to do this.
+#
diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile
new file mode 100644
index 0000000..573bca7
--- /dev/null
+++ b/code/fe310/eos/Makefile
@@ -0,0 +1,18 @@
+FE310_HOME=/opt/my/freedom-e-sdk
+
+CC=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-gcc
+AR=$(FE310_HOME)/work/build/riscv-gnu-toolchain/riscv64-unknown-elf/prefix/bin/riscv64-unknown-elf-ar
+
+CFLAGS=-O3 -fno-builtin-printf -march=rv32imac -mabi=ilp32 -mcmodel=medany -I$(FE310_HOME)/bsp/include -I$(FE310_HOME)/bsp/drivers -I$(FE310_HOME)/bsp/env -I$(FE310_HOME)/bsp/env/freedom-e300-hifive1 -I../..
+
+obj = msgq.o event.o interrupt.o timer.o net.o eos.o ecp.o
+
+
+%.o: %.c %.h
+ $(CC) $(CFLAGS) -c $<
+
+all: $(obj)
+ $(AR) rcs libeos.a $(obj)
+
+clean:
+ rm -f *.o *.a \ No newline at end of file
diff --git a/code/fe310/eos/ecp.c b/code/fe310/eos/ecp.c
new file mode 100644
index 0000000..433e693
--- /dev/null
+++ b/code/fe310/eos/ecp.c
@@ -0,0 +1,66 @@
+#include <stddef.h>
+#include <string.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+#include "event.h"
+#include "timer.h"
+#include "net.h"
+
+#include "ecp.h"
+
+static ECPSocket *_sock = NULL;
+
+static unsigned char net_buf_reserved = 0;
+static void timer_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ int ok = eos_net_acquire(net_buf_reserved);
+ if (ok) {
+ ecp_cts_t next = ecp_timer_exe(_sock);
+ if (next) {
+ uint32_t tick = next * (uint64_t)RTC_FREQ / 1000;
+ eos_timer_set(tick, 1);
+ }
+ eos_net_release(1);
+ net_buf_reserved = 0;
+ } else {
+ net_buf_reserved = 1;
+ eos_evtq_push(EOS_EVT_TIMER, NULL, 0);
+ }
+}
+
+static void packet_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ ECPNetAddr addr;
+ size_t addr_len = sizeof(addr.host) + sizeof(addr.port);
+
+ ECP2Buffer bufs;
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pld_buf[ECP_MAX_PLD];
+
+ bufs.packet = &packet;
+ bufs.payload = &payload;
+
+ packet.buffer = buffer+addr_len;
+ packet.size = ECP_MAX_PKT;
+ payload.buffer = pld_buf;
+ payload.size = ECP_MAX_PLD;
+
+ memcpy(addr.host, buffer, sizeof(addr.host));
+ memcpy(&addr.port, buffer+sizeof(addr.host), sizeof(addr.port));
+ ssize_t rv = ecp_pkt_handle(_sock, &addr, NULL, &bufs, len-addr_len);
+ if (bufs.packet->buffer) eos_net_free(buffer, 0);
+ eos_net_release(0);
+}
+
+int ecp_init(ECPContext *ctx) {
+ int rv;
+
+ rv = ecp_ctx_create(ctx);
+ if (rv) return rv;
+
+ eos_evtq_set_handler(EOS_EVT_TIMER, timer_handler);
+ eos_evtq_set_handler(EOS_EVT_MASK_NET | EOS_NET_CMD_PKT, packet_handler);
+
+ return ECP_OK;
+} \ No newline at end of file
diff --git a/code/fe310/eos/ecp.h b/code/fe310/eos/ecp.h
new file mode 100644
index 0000000..95aed31
--- /dev/null
+++ b/code/fe310/eos/ecp.h
@@ -0,0 +1,3 @@
+#include <ecp/core.h>
+
+int ecp_init(ECPContext *ctx); \ No newline at end of file
diff --git a/code/fe310/eos/eos.c b/code/fe310/eos/eos.c
new file mode 100644
index 0000000..3ad3b68
--- /dev/null
+++ b/code/fe310/eos/eos.c
@@ -0,0 +1,17 @@
+#include "event.h"
+#include "interrupt.h"
+#include "timer.h"
+#include "net.h"
+
+#include "eos.h"
+
+void eos_init(void) {
+ eos_evtq_init();
+ eos_intr_init();
+ eos_timer_init();
+ eos_net_init();
+}
+
+void eos_start(void) {
+ eos_net_start(15);
+} \ No newline at end of file
diff --git a/code/fe310/eos/eos.h b/code/fe310/eos/eos.h
new file mode 100644
index 0000000..938030e
--- /dev/null
+++ b/code/fe310/eos/eos.h
@@ -0,0 +1,6 @@
+#define EOS_OK 0
+#define EOS_ERR_Q_FULL -10
+
+void eos_init(void);
+void eos_start(void);
+
diff --git a/code/fe310/eos/event.c b/code/fe310/eos/event.c
new file mode 100644
index 0000000..25f1fa1
--- /dev/null
+++ b/code/fe310/eos/event.c
@@ -0,0 +1,85 @@
+#include <stdio.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+#include "eos.h"
+#include "msgq.h"
+#include "net.h"
+#include "timer.h"
+#include "event.h"
+
+static EOSMsgQ event_q;
+static EOSMsgItem event_q_array[EOS_EVT_SIZE_Q];
+
+static eos_evt_fptr_t evt_net_handler[EOS_NET_MAX_CMD];
+static eos_evt_fptr_t evt_timer_handler = NULL;
+static eos_evt_fptr_t evt_ui_handler = NULL;
+
+static void bad_handler(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ printf("bad handler: %d\n", cmd);
+}
+
+void eos_evtq_init(void) {
+ int i;
+
+ for (i=0; i<EOS_NET_MAX_CMD; i++) {
+ evt_net_handler[i] = bad_handler;
+ }
+ evt_timer_handler = bad_handler;
+ evt_ui_handler = bad_handler;
+ eos_msgq_init(&event_q, event_q_array, EOS_EVT_SIZE_Q);
+}
+
+int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ return eos_msgq_push(&event_q, cmd, buffer, len);
+}
+
+void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len) {
+ eos_msgq_pop(&event_q, cmd, buffer, len);
+}
+
+void eos_evtq_handle(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ if (cmd & EOS_EVT_MASK_NET) {
+ cmd &= ~EOS_EVT_MASK_NET;
+ if (cmd < EOS_NET_MAX_CMD) {
+ evt_net_handler[cmd](cmd, buffer, len);
+ } else {
+ bad_handler(cmd, buffer, len);
+ }
+ } else if (cmd == EOS_EVT_TIMER) {
+ evt_timer_handler(cmd, buffer, len);
+ } else if (cmd == EOS_EVT_UI) {
+ evt_ui_handler(cmd, buffer, len);
+ }
+}
+
+void eos_evtq_loop(void) {
+ unsigned char cmd;
+ unsigned char *buffer;
+ uint16_t len;
+ volatile int foo = 1;
+
+ while(foo) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ eos_evtq_pop(&cmd, &buffer, &len);
+ if (cmd) {
+ set_csr(mstatus, MSTATUS_MIE);
+ eos_evtq_handle(cmd, buffer, len);
+ clear_csr(mstatus, MSTATUS_MIE);
+ } else {
+ // asm volatile ("wfi");
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+}
+
+void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler) {
+ if (cmd & EOS_EVT_MASK_NET) {
+ evt_net_handler[cmd & ~EOS_EVT_MASK_NET] = handler;
+ } else if (cmd == EOS_EVT_TIMER) {
+ evt_timer_handler = handler;
+ } else if (cmd == EOS_EVT_UI) {
+ evt_ui_handler = handler;
+ }
+} \ No newline at end of file
diff --git a/code/fe310/eos/event.h b/code/fe310/eos/event.h
new file mode 100644
index 0000000..21079b4
--- /dev/null
+++ b/code/fe310/eos/event.h
@@ -0,0 +1,16 @@
+#include <stdint.h>
+
+#define EOS_EVT_MASK_NET 0x80
+#define EOS_EVT_TIMER 0x01
+#define EOS_EVT_UI 0x02
+
+#define EOS_EVT_SIZE_Q 4
+
+typedef void (*eos_evt_fptr_t) (unsigned char, unsigned char *, uint16_t);
+
+void eos_evtq_init(void);
+int eos_evtq_push(unsigned char cmd, unsigned char *buffer, uint16_t len);
+void eos_evtq_pop(unsigned char *cmd, unsigned char **buffer, uint16_t *len);
+void eos_evtq_handle(unsigned char cmd, unsigned char *buffer, uint16_t len);
+void eos_evtq_loop(void);
+void eos_evtq_set_handler(unsigned char cmd, eos_evt_fptr_t handler); \ No newline at end of file
diff --git a/code/fe310/eos/interrupt.c b/code/fe310/eos/interrupt.c
new file mode 100644
index 0000000..def1a24
--- /dev/null
+++ b/code/fe310/eos/interrupt.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "encoding.h"
+#include "platform.h"
+#include "plic/plic_driver.h"
+#include "interrupt.h"
+
+// Global Instance data for the PLIC
+// for use by the PLIC Driver.
+static plic_instance_t plic;
+
+static eos_intr_fptr_t ext_interrupt_handler[PLIC_NUM_INTERRUPTS];
+
+void handle_m_ext_interrupt(void) {
+ plic_source int_num = PLIC_claim_interrupt(&plic);
+ if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num])) {
+ ext_interrupt_handler[int_num]();
+ } else {
+ printf("handle_m_ext_interrupt error\n\n");
+ exit(1 + (uintptr_t) int_num);
+ }
+ PLIC_complete_interrupt(&plic, int_num);
+}
+
+void eos_intr_init(void) {
+ for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){
+ ext_interrupt_handler[i] = NULL;
+ }
+
+ /**************************************************************************
+ * Set up the PLIC
+ **************************************************************************/
+ PLIC_init(&plic,
+ PLIC_CTRL_ADDR,
+ PLIC_NUM_INTERRUPTS,
+ PLIC_NUM_PRIORITIES);
+
+ // Enable Global (PLIC) interrupts.
+ set_csr(mie, MIP_MEIP);
+
+ // Enable all interrupts
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
+void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler) {
+ ext_interrupt_handler[int_num] = handler;
+ PLIC_enable_interrupt(&plic, int_num);
+ PLIC_set_priority(&plic, int_num, priority);
+}
diff --git a/code/fe310/eos/interrupt.h b/code/fe310/eos/interrupt.h
new file mode 100644
index 0000000..7ef81b8
--- /dev/null
+++ b/code/fe310/eos/interrupt.h
@@ -0,0 +1,8 @@
+#include <stdint.h>
+
+// Structures for registering different interrupt handlers
+// for different parts of the application.
+typedef void (*eos_intr_fptr_t) (void);
+
+void eos_intr_init(void);
+void eos_intr_set_handler(uint8_t int_num, uint8_t priority, eos_intr_fptr_t handler);
diff --git a/code/fe310/eos/msgq.c b/code/fe310/eos/msgq.c
new file mode 100644
index 0000000..d242c69
--- /dev/null
+++ b/code/fe310/eos/msgq.c
@@ -0,0 +1,66 @@
+#include <stddef.h>
+
+#include "eos.h"
+#include "msgq.h"
+
+#define EOS_MSGQ_IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1))
+
+void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) {
+ msgq->idx_r = 0;
+ msgq->idx_w = 0;
+ msgq->array = array;
+ msgq->size = size;
+}
+
+int eos_msgq_push(EOSMsgQ *msgq, unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ if (msgq->idx_w - msgq->idx_r == msgq->size) return EOS_ERR_Q_FULL;
+
+ uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_w, msgq->size);
+ msgq->array[idx].cmd = cmd;
+ msgq->array[idx].buffer = buffer;
+ msgq->array[idx].len = len;
+ msgq->idx_w++;
+ return EOS_OK;
+}
+
+void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *cmd, unsigned char **buffer, uint16_t *len) {
+ if (msgq->idx_r == msgq->idx_w) {
+ *cmd = 0;
+ *buffer = NULL;
+ } else {
+ uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size);
+ *cmd = msgq->array[idx].cmd;
+ *buffer = msgq->array[idx].buffer;
+ *len = msgq->array[idx].len;
+ msgq->idx_r++;
+ }
+}
+
+void eos_msgq_get(EOSMsgQ *msgq, unsigned char cmd, unsigned char **buffer, uint16_t *len) {
+ uint8_t idx = EOS_MSGQ_IDX_MASK(msgq->idx_r, msgq->size);
+ unsigned char _cmd = msgq->array[idx].cmd;
+ EOSMsgItem *tmp_item = &msgq->array[idx];
+
+ *buffer = msgq->array[idx].buffer;
+ *len = msgq->array[idx].len;
+ if (_cmd == cmd) {
+ msgq->idx_r++;
+ return;
+ }
+ for (idx = msgq->idx_r + 1; idx < msgq->idx_w; idx++) {
+ *tmp_item = msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)];
+ msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].cmd = _cmd;
+ msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].buffer = *buffer;
+ msgq->array[EOS_MSGQ_IDX_MASK(idx, msgq->size)].len = *len;
+ _cmd = tmp_item->cmd;
+ *buffer = tmp_item->buffer;
+ *len = tmp_item->len;
+ if (_cmd == cmd) {
+ msgq->idx_r++;
+ return;
+ }
+ }
+ *buffer = NULL;
+ *len = 0;
+}
+
diff --git a/code/fe310/eos/msgq.h b/code/fe310/eos/msgq.h
new file mode 100644
index 0000000..05a5d80
--- /dev/null
+++ b/code/fe310/eos/msgq.h
@@ -0,0 +1,19 @@
+#include <stdint.h>
+
+typedef struct EOSMsgItem {
+ unsigned char cmd;
+ unsigned char *buffer;
+ uint16_t len;
+} EOSMsgItem;
+
+typedef struct EOSMsgQ {
+ uint8_t idx_r;
+ uint8_t idx_w;
+ uint8_t size;
+ EOSMsgItem *array;
+} EOSMsgQ;
+
+void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size);
+int eos_msgq_push(EOSMsgQ *msgq, unsigned char cmd, unsigned char *buffer, uint16_t len);
+void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *cmd, unsigned char **buffer, uint16_t *len);
+void eos_msgq_get(EOSMsgQ *msgq, unsigned char cmd, unsigned char **buffer, uint16_t *len); \ No newline at end of file
diff --git a/code/fe310/eos/net.c b/code/fe310/eos/net.c
new file mode 100644
index 0000000..080da72
--- /dev/null
+++ b/code/fe310/eos/net.c
@@ -0,0 +1,365 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "encoding.h"
+#include "platform.h"
+#include "plic/plic_driver.h"
+
+#include "eos.h"
+#include "msgq.h"
+#include "event.h"
+#include "interrupt.h"
+#include "net.h"
+#include "spi.h"
+
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
+#define SPI_BUFQ_IDX_MASK(IDX) ((IDX) & (SPI_SIZE_BUFQ - 1))
+
+static volatile uint8_t spi_res = 0;
+static volatile uint8_t spi_res_next = 0;
+static volatile unsigned char *spi_res_buf = NULL;
+
+static EOSMsgQ spi_sndq;
+static EOSMsgItem spi_sndq_array[SPI_SIZE_BUFQ];
+
+static SPIBufQ spi_bufq;
+static unsigned char spi_bufq_array[SPI_SIZE_BUFQ][SPI_SIZE_BUF];
+
+static int spi_bufq_push(unsigned char *buffer) {
+ spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_w++)] = buffer;
+}
+
+static unsigned char *spi_bufq_pop(void) {
+ if (spi_bufq.idx_r == spi_bufq.idx_w) return NULL;
+ return spi_bufq.array[SPI_BUFQ_IDX_MASK(spi_bufq.idx_r++)];
+}
+
+static volatile uint8_t spi_rdy = 0;
+static volatile uint8_t spi_cts = 0;
+static volatile uint8_t spi_rts = 0;
+static SPIBuffer spi_buffer;
+
+static void spi_reset(void) {
+ int i;
+ volatile uint32_t r;
+
+ spi_cts = 0;
+ // before starting a transaction, set SPI peripheral to desired mode
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
+
+ while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL);
+ SPI1_REG(SPI_REG_TXFIFO) = 0;
+ while ((r = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
+
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
+}
+
+static void spi_xchg(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ volatile uint32_t r1, r2;
+
+ spi_cts = 0;
+ spi_buffer.buffer = buffer;
+ spi_buffer.len_rx = 0;
+ spi_buffer.idx_tx = 0;
+ spi_buffer.idx_rx = 0;
+
+ if (spi_res_buf == NULL) {
+ if (cmd & EOS_NET_CMD_FLAG_ONEW) {
+ spi_res_next = 1;
+ } else if (spi_res) {
+ cmd |= EOS_NET_CMD_FLAG_ONEW;
+ }
+ } else if (cmd & EOS_NET_CMD_FLAG_ONEW) {
+ cmd &= ~EOS_NET_CMD_FLAG_ONEW;
+ }
+
+ // before starting a transaction, set SPI peripheral to desired mode
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
+
+ while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL);
+ SPI1_REG(SPI_REG_TXFIFO) = ((cmd << 3) | (len >> 8)) & 0xFF;
+
+ while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL);
+ SPI1_REG(SPI_REG_TXFIFO) = len & 0xFF;
+
+ while ((r1 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
+ while ((r2 = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
+
+ if (cmd & EOS_NET_CMD_FLAG_ONEW) {
+ r1 = 0;
+ r2 = 0;
+ }
+
+ spi_buffer.cmd = ((r1 & 0xFF) >> 3);
+ spi_buffer.len_rx = ((r1 & 0x07) << 8);
+
+ spi_buffer.len_rx |= (r2 & 0xFF);
+ spi_buffer.len = MAX(len, spi_buffer.len_rx);
+
+ // Work around esp32 bug
+ if (spi_buffer.len < 6) {
+ spi_buffer.len = 6;
+ } else if ((spi_buffer.len + 2) % 4 != 0) {
+ spi_buffer.len = ((spi_buffer.len + 2)/4 + 1) * 4 - 2;
+ }
+
+ SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_CHUNK/2);
+ SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(SPI_SIZE_CHUNK - 1);
+ SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM | SPI_IP_RXWM;
+}
+
+static int spi_xchg_next(unsigned char *_buffer) {
+ unsigned char cmd;
+ unsigned char *buffer = NULL;
+ uint16_t len;
+
+ eos_msgq_pop(&spi_sndq, &cmd, &buffer, &len);
+ if (cmd) {
+ spi_xchg(cmd, buffer, len);
+ } else if (spi_rts) {
+ if (_buffer == NULL) _buffer = spi_bufq_pop();
+ if (_buffer) {
+ spi_xchg(0, _buffer, 0);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void spi_xchg_handler(void) {
+ int i;
+
+ if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) {
+ uint16_t sz_chunk = MIN(spi_buffer.len - spi_buffer.idx_tx, SPI_SIZE_CHUNK);
+ for (i=0; i<sz_chunk; i++) {
+ if (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL) break;
+ SPI1_REG(SPI_REG_TXFIFO) = spi_buffer.buffer[spi_buffer.idx_tx+i];
+ }
+ spi_buffer.idx_tx += i;
+ }
+
+ for (i=0; i<spi_buffer.idx_tx - spi_buffer.idx_rx; i++) {
+ volatile uint32_t x = SPI1_REG(SPI_REG_RXFIFO);
+ if (x & SPI_RXFIFO_EMPTY) break;
+ spi_buffer.buffer[spi_buffer.idx_rx+i] = x & 0xFF;
+ }
+ spi_buffer.idx_rx += i;
+
+ if (spi_buffer.idx_rx == spi_buffer.len) {
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
+ SPI1_REG(SPI_REG_IE) = 0x0;
+ if (spi_buffer.cmd) {
+ int r = eos_evtq_push(spi_buffer.cmd | EOS_EVT_MASK_NET, spi_buffer.buffer, spi_buffer.len_rx);
+ if (r) spi_bufq_push(spi_buffer.buffer);
+ } else if ((spi_res || spi_res_next) && (spi_res_buf == NULL)) {
+ spi_res_buf = spi_buffer.buffer;
+ spi_res_next = 0;
+ } else {
+ spi_bufq_push(spi_buffer.buffer);
+ }
+ } else if (spi_buffer.idx_tx == spi_buffer.len) {
+ SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(spi_buffer.len - spi_buffer.idx_rx - 1, SPI_SIZE_CHUNK - 1));
+ SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;
+ }
+}
+
+static void spi_cts_hanler(void) {
+ GPIO_REG(GPIO_RISE_IP) = (0x1 << SPI_GPIO_CTS_OFFSET);
+ spi_cts = 1;
+
+ if (spi_rdy) {
+ spi_xchg_next(NULL);
+ } else {
+ uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2);
+ GPIO_REG(GPIO_IOF_EN) &= ~iof_mask;
+ }
+}
+
+static void spi_rts_hanler(void) {
+ uint32_t rts_offset = (0x1 << SPI_GPIO_RTS_OFFSET);
+ if (GPIO_REG(GPIO_RISE_IP) & rts_offset) {
+ GPIO_REG(GPIO_RISE_IP) = rts_offset;
+ spi_rts = 1;
+ if (spi_rdy && spi_cts) spi_reset();
+ }
+
+ if (GPIO_REG(GPIO_FALL_IP) & rts_offset) {
+ GPIO_REG(GPIO_FALL_IP) = rts_offset;
+ spi_rts = 0;
+ }
+}
+
+void eos_net_init(void) {
+ int i;
+
+ spi_bufq.idx_r = 0;
+ spi_bufq.idx_w = 0;
+ for (i=0; i<SPI_SIZE_BUFQ; i++) {
+ spi_bufq_push(spi_bufq_array[i]);
+ }
+ eos_msgq_init(&spi_sndq, spi_sndq_array, SPI_SIZE_BUFQ);
+ GPIO_REG(GPIO_IOF_SEL) &= ~SPI_IOF_MASK;
+ GPIO_REG(GPIO_IOF_EN) |= SPI_IOF_MASK;
+ eos_intr_set_handler(INT_SPI1_BASE, 5, spi_xchg_handler);
+
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << SPI_GPIO_CTS_OFFSET);
+ GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << SPI_GPIO_CTS_OFFSET);
+ GPIO_REG(GPIO_INPUT_EN) |= (0x1 << SPI_GPIO_CTS_OFFSET);
+ GPIO_REG(GPIO_RISE_IE) |= (0x1 << SPI_GPIO_CTS_OFFSET);
+ eos_intr_set_handler(INT_GPIO_BASE + SPI_GPIO_CTS_OFFSET, 5, spi_cts_hanler);
+
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(0x1 << SPI_GPIO_RTS_OFFSET);
+ GPIO_REG(GPIO_PULLUP_EN) |= (0x1 << SPI_GPIO_RTS_OFFSET);
+ GPIO_REG(GPIO_INPUT_EN) |= (0x1 << SPI_GPIO_RTS_OFFSET);
+ GPIO_REG(GPIO_RISE_IE) |= (0x1 << SPI_GPIO_RTS_OFFSET);
+ GPIO_REG(GPIO_FALL_IE) |= (0x1 << SPI_GPIO_RTS_OFFSET);
+ eos_intr_set_handler(INT_GPIO_BASE + SPI_GPIO_RTS_OFFSET, 5, spi_rts_hanler);
+}
+
+void eos_net_start(uint32_t sckdiv) {
+ uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2);
+
+ GPIO_REG(GPIO_IOF_SEL) &= ~iof_mask;
+ GPIO_REG(GPIO_IOF_EN) |= iof_mask;
+
+ SPI1_REG(SPI_REG_SCKDIV) = sckdiv;
+ SPI1_REG(SPI_REG_SCKMODE) = SPI_MODE0;
+ SPI1_REG(SPI_REG_FMT) = SPI_FMT_PROTO(SPI_PROTO_S) |
+ SPI_FMT_ENDIAN(SPI_ENDIAN_MSB) |
+ SPI_FMT_DIR(SPI_DIR_RX) |
+ SPI_FMT_LEN(8);
+
+ // enable CS pin for selected channel/pin
+ SPI1_REG(SPI_REG_CSID) = 2;
+
+ // There is no way here to change the CS polarity.
+ // SPI1_REG(SPI_REG_CSDEF) = 0xFFFF;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ spi_rdy = 1;
+ if (spi_cts) spi_xchg_next(NULL);
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
+void eos_net_stop(void) {
+ volatile uint8_t done = 0;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ spi_rdy = 0;
+ if (spi_cts) {
+ uint32_t iof_mask = ((uint32_t)1 << IOF_SPI1_SS2);
+ GPIO_REG(GPIO_IOF_EN) &= ~iof_mask;
+ done = 1;
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+
+ while (!done) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ done = spi_cts;
+ if (!done) asm volatile ("wfi");
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+}
+
+int eos_net_reserve(unsigned char *buffer) {
+ int rv = EOS_OK;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ spi_res++;
+ if (spi_res_buf == NULL) {
+ spi_res_buf = buffer;
+ } else {
+ rv = spi_bufq_push(buffer);
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
+}
+
+int eos_net_acquire(unsigned char reserved) {
+ int ret = 0;
+
+ if (reserved) {
+ while (!ret) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (spi_res_buf) {
+ ret = 1;
+ } else {
+ asm volatile ("wfi");
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ } else {
+ clear_csr(mstatus, MSTATUS_MIE);
+ spi_res++;
+ spi_res_buf = spi_bufq_pop();
+ ret = (spi_res_buf != NULL);
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ return ret;
+}
+
+int eos_net_release(unsigned char reserved) {
+ int rv = EOS_OK;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (reserved) spi_res--;
+ if (!spi_res && spi_res_buf) {
+ rv = spi_bufq_push((unsigned char *)spi_res_buf);
+ if (!rv) spi_res_buf = NULL;
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
+}
+
+unsigned char *eos_net_alloc(void) {
+ volatile unsigned char *ret = NULL;
+
+ while (ret == NULL) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (spi_res_buf) {
+ ret = spi_res_buf;
+ spi_res_buf = NULL;
+ } else {
+ asm volatile ("wfi");
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+
+ return (unsigned char *)ret;
+}
+
+int eos_net_free(unsigned char *buffer, unsigned char reserve_next) {
+ int rv = EOS_OK;
+ uint8_t do_release = 1;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ if ((spi_res || reserve_next) && (spi_res_buf == NULL)) {
+ spi_res_buf = buffer;
+ } else {
+ if (spi_rdy && spi_cts) do_release = spi_xchg_next(buffer);
+ if (do_release) rv = spi_bufq_push(buffer);
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
+}
+
+int eos_net_send(unsigned char cmd, unsigned char *buffer, uint16_t len) {
+ int rv = EOS_OK;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (spi_rdy && spi_cts) {
+ spi_xchg(cmd, buffer, len);
+ } else {
+ rv = eos_msgq_push(&spi_sndq, cmd, buffer, len);
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
+}
diff --git a/code/fe310/eos/net.h b/code/fe310/eos/net.h
new file mode 100644
index 0000000..0091c3c
--- /dev/null
+++ b/code/fe310/eos/net.h
@@ -0,0 +1,20 @@
+#include <stdint.h>
+
+#define EOS_NET_CMD_FLAG_ONEW 0x10
+
+#define EOS_NET_CMD_CONNECT 1
+#define EOS_NET_CMD_DISCONNECT 2
+#define EOS_NET_CMD_SCAN 3
+#define EOS_NET_CMD_PKT 4
+
+#define EOS_NET_MAX_CMD 8
+
+void eos_net_init(void);
+void eos_net_start(uint32_t sckdiv);
+void eos_net_stop(void);
+int eos_net_reserve(unsigned char *buffer);
+int eos_net_acquire(unsigned char reserved);
+int eos_net_release(unsigned char reserved);
+unsigned char *eos_net_alloc(void);
+int eos_net_free(unsigned char *buffer, unsigned char reserve_next);
+int eos_net_send(unsigned char cmd, unsigned char *buffer, uint16_t len);
diff --git a/code/fe310/eos/spi.h b/code/fe310/eos/spi.h
new file mode 100644
index 0000000..88e54bb
--- /dev/null
+++ b/code/fe310/eos/spi.h
@@ -0,0 +1,32 @@
+#include <stdint.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+#define SPI_MODE0 0x00
+#define SPI_MODE1 0x01
+#define SPI_MODE2 0x02
+#define SPI_MODE3 0x03
+
+#define SPI_SIZE_BUF 1500
+#define SPI_SIZE_CHUNK 4
+#define SPI_SIZE_BUFQ 4
+#define SPI_GPIO_CTS_OFFSET PIN_2_OFFSET
+#define SPI_GPIO_RTS_OFFSET PIN_3_OFFSET
+#define SPI_IOF_MASK (((uint32_t)1 << IOF_SPI1_SCK) | ((uint32_t)1 << IOF_SPI1_MOSI) | ((uint32_t)1 << IOF_SPI1_MISO))
+
+typedef struct SPIBuffer {
+ unsigned char cmd;
+ unsigned char *buffer;
+ uint16_t len;
+ uint16_t len_rx;
+ uint16_t idx_tx;
+ uint16_t idx_rx;
+} SPIBuffer;
+
+typedef struct SPIBufQ {
+ uint8_t idx_r;
+ uint8_t idx_w;
+ unsigned char *array[SPI_SIZE_BUFQ];
+} SPIBufQ;
+
diff --git a/code/fe310/eos/timer.c b/code/fe310/eos/timer.c
new file mode 100644
index 0000000..0a07ed9
--- /dev/null
+++ b/code/fe310/eos/timer.c
@@ -0,0 +1,86 @@
+#include <stddef.h>
+#include <stdio.h>
+
+#include "encoding.h"
+#include "platform.h"
+#include "event.h"
+#include "timer.h"
+
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
+
+static eos_timer_fptr_t timer_ext_handler = NULL;
+volatile uint64_t timer_next = 0;
+volatile uint64_t timer_next_evt = 0;
+
+void handle_m_time_interrupt(void) {
+ volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME);
+ volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
+ uint64_t now = *mtime;
+
+ if (timer_next && (timer_next <= now)) {
+ uint32_t next = timer_ext_handler();
+ if (next) {
+ timer_next = now + next;
+ } else {
+ timer_next = 0;
+ }
+ }
+ if (timer_next_evt && (timer_next_evt <= now)) {
+ eos_evtq_push(EOS_EVT_TIMER, NULL, 0);
+ timer_next_evt = 0;
+ }
+ *mtimecmp = (timer_next && timer_next_evt) ? MIN(timer_next, timer_next_evt) : (timer_next ? timer_next : timer_next_evt);
+ if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP);
+}
+
+void eos_timer_init(void) {
+ volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
+ *mtimecmp = 0;
+ clear_csr(mie, MIP_MTIP);
+}
+
+void eos_timer_set(uint32_t tick, unsigned char is_evt) {
+ volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME);
+ volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
+
+ clear_csr(mstatus, MSTATUS_MIE);
+
+ uint64_t now = *mtime;
+ uint64_t then = *mtimecmp;
+ uint64_t next = now + tick;
+ if (is_evt) {
+ if ((timer_next_evt == 0) || (next < timer_next_evt)) timer_next_evt = next;
+ next = timer_next ? MIN(timer_next, timer_next_evt) : timer_next_evt;
+ } else if (timer_ext_handler) {
+ if ((timer_next == 0) || (next < timer_next)) timer_next = next;
+ next = timer_next_evt ? MIN(timer_next, timer_next_evt) : timer_next;
+ }
+ if ((then == 0) || (next < then)) *mtimecmp = next;
+ if (then == 0) set_csr(mie, MIP_MTIP);
+
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
+void eos_timer_clear(unsigned char is_evt) {
+ volatile uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
+
+ clear_csr(mstatus, MSTATUS_MIE);
+
+ if (is_evt) {
+ timer_next_evt = 0;
+ *mtimecmp = timer_next;
+ } else {
+ timer_next = 0;
+ *mtimecmp = timer_next_evt;
+ }
+ if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP);
+
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
+void eos_timer_set_handler(eos_timer_fptr_t handler) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ timer_ext_handler = handler;
+ set_csr(mstatus, MSTATUS_MIE);
+}
diff --git a/code/fe310/eos/timer.h b/code/fe310/eos/timer.h
new file mode 100644
index 0000000..929283b
--- /dev/null
+++ b/code/fe310/eos/timer.h
@@ -0,0 +1,7 @@
+#include <stdint.h>
+
+typedef uint32_t (*eos_timer_fptr_t) (void);
+
+void eos_timer_init(void);
+void eos_timer_set(uint32_t tick, unsigned char is_evt);
+void eos_timer_set_handler(eos_timer_fptr_t handler);
diff --git a/code/platform b/code/platform
index 545b475..0781395 100755
--- a/code/platform
+++ b/code/platform
@@ -10,5 +10,5 @@ fi
PLATFORM=$1
-ln -sf $BASEDIR/Makefile.$PLATFORM $BASEDIR/Makefile.platform
-ln -sf $BASEDIR/config_$PLATFORM.h $BASEDIR/config.h \ No newline at end of file
+ln -sf ./Makefile.$PLATFORM $BASEDIR/ecp/Makefile.platform
+ln -sf ./config_$PLATFORM.h $BASEDIR/ecp/config.h \ No newline at end of file
diff --git a/code/test/Makefile b/code/test/Makefile
index 4172420..13fa476 100644
--- a/code/test/Makefile
+++ b/code/test/Makefile
@@ -1,4 +1,4 @@
-include ../Makefile.platform
+include ../ecp/Makefile.platform
CFLAGS=$(CFLAGS_PL) -I../ecp -I../util -Wno-int-to-void-pointer-cast
LDFLAGS=$(LDFLAGS_PL)
diff --git a/code/test/stress.c b/code/test/stress.c
index d6bc74a..6bc5a64 100644
--- a/code/test/stress.c
+++ b/code/test/stress.c
@@ -94,7 +94,9 @@ void *sender(ECPConnection *c) {
usleep(rnd % (2000000/msg_rate));
ecp_pld_set_type(pld_buf, MTYPE_MSG);
- ssize_t _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0));
+ ssize_t _rv = 0;
+ // XXX refactor
+ // _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0));
if (c_start && (_rv > 0)) {
pthread_mutex_lock(&t_mtx[idx]);
t_sent[idx]++;
@@ -153,7 +155,8 @@ ssize_t handle_msg_s(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigne
payload.size = ECP_MAX_PLD;
ecp_pld_set_type(pld_buf, MTYPE_MSG);
- ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1000, 0));
+ // XXX refactor
+ // ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1000, 0));
return s;
}
diff --git a/code/util/Makefile b/code/util/Makefile
index 0645ace..a896fc2 100644
--- a/code/util/Makefile
+++ b/code/util/Makefile
@@ -1,4 +1,4 @@
-include ../Makefile.platform
+include ../ecp/Makefile.platform
CFLAGS=$(CFLAGS_PL) -I../ecp
LDFLAGS=$(LDFLAGS_PL)
diff --git a/code/util/keydump b/code/util/keydump
new file mode 100755
index 0000000..9a884dc
--- /dev/null
+++ b/code/util/keydump
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+hexdump -e '16/1 "0x%02X, " "\n"' $@