diff options
Diffstat (limited to 'ecp/src/ecp/ext')
-rw-r--r-- | ecp/src/ecp/ext/Makefile | 13 | ||||
-rw-r--r-- | ecp/src/ecp/ext/ext.c | 69 | ||||
-rw-r--r-- | ecp/src/ecp/ext/frag.c | 129 | ||||
-rw-r--r-- | ecp/src/ecp/ext/frag.h | 13 |
4 files changed, 224 insertions, 0 deletions
diff --git a/ecp/src/ecp/ext/Makefile b/ecp/src/ecp/ext/Makefile new file mode 100644 index 0000000..0e61e83 --- /dev/null +++ b/ecp/src/ecp/ext/Makefile @@ -0,0 +1,13 @@ +include ../common.mk + +obj = ext.o frag.o rbuf.o rbuf_send.o rbuf_recv.o msgq.o + + +%.o: %.c + $(CC) $(CFLAGS) -c $< + +all: $(obj) + $(AR) rcs libecpext.a $(obj) + +clean: + rm -f *.o *.a diff --git a/ecp/src/ecp/ext/ext.c b/ecp/src/ecp/ext/ext.c new file mode 100644 index 0000000..d407e80 --- /dev/null +++ b/ecp/src/ecp/ext/ext.c @@ -0,0 +1,69 @@ +#include <stdlib.h> + +#include <core.h> +#include <ext.h> + +#include "rbuf.h" +#include "frag.h" + +int ecp_ext_err_handle(ECPConnection *conn, unsigned char mtype, int err) { + ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); + + if (_conn) return ecp_rbuf_err_handle(_conn, mtype, err); + return ECP_PASS; +} + +int ecp_ext_conn_open(ECPConnection *conn) { + ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); + + if (_conn) ecp_rbuf_start(_conn); + return ECP_OK; +} + +void ecp_ext_conn_destroy(ECPConnection *conn) { + ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); + if (_conn) ecp_rbuf_destroy(_conn); +} + +ssize_t ecp_ext_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { + ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); + + if (_conn) return ecp_rbuf_msg_handle(_conn, seq, mtype, msg, msg_size, bufs); + return 0; +} + +ssize_t ecp_ext_pld_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) { + ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); + + if (_conn && _conn->recv) return ecp_rbuf_store(_conn, seq, payload, pld_size); + return 0; +} + +ssize_t ecp_ext_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) { + unsigned char mtype; + int rv; + + rv = ecp_pld_get_type(payload, pld_size, &mtype); + if (rv) return rv; + + if (mtype & ECP_MTYPE_FLAG_FRAG) { + return ecp_pld_defrag(conn, seq, mtype, payload, pld_size); + } else { + return 0; + } +} + +ssize_t ecp_ext_pld_send(ECPConnection *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr) { + ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); + + if (_conn && _conn->send) return ecp_rbuf_pld_send(_conn, payload, pld_size, packet, pkt_size, ti); + return 0; +} + +ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) { + if (ECP_SIZE_PKT_BUF(msg_size, mtype, conn) > ECP_MAX_PKT) { + return ecp_msg_frag(conn, mtype, msg, msg_size, packet, payload); + } else { + return 0; + } +} diff --git a/ecp/src/ecp/ext/frag.c b/ecp/src/ecp/ext/frag.c new file mode 100644 index 0000000..ce87d81 --- /dev/null +++ b/ecp/src/ecp/ext/frag.c @@ -0,0 +1,129 @@ +#include <stdlib.h> +#include <string.h> + +#include <core.h> + +#include "rbuf.h" +#include "frag.h" + +int ecp_frag_iter_init(ECPRBConn *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size) { + memset(iter, 0, sizeof(ECPFragIter)); + iter->buffer = buffer; + iter->buf_size = buf_size; + + conn->iter = iter; + return ECP_OK; +} + +ECPFragIter *ecp_frag_iter_get(ECPRBConn *conn) { + return conn->iter; +} + +void ecp_frag_iter_reset(ECPFragIter *iter) { + iter->seq = 0; + iter->frag_cnt = 0; + iter->pld_size = 0; +} + +ssize_t ecp_msg_frag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) { + unsigned char *msg_buf; + unsigned char *pld_buf; + size_t pld_size; + size_t frag_size, frag_size_final; + ecp_nonce_t nonce, nonce_start; + int pkt_cnt = 0; + int i; + + mtype |= ECP_MTYPE_FLAG_FRAG; + frag_size = ECP_MAX_PKT - ECP_SIZE_PKT_BUF(0, mtype, conn); + pkt_cnt = msg_size / frag_size; + frag_size_final = msg_size - frag_size * pkt_cnt; + if (frag_size_final) pkt_cnt++; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + nonce_start = conn->nonce_out; + conn->nonce_out += pkt_cnt; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + pld_buf = payload->buffer; + pld_size = payload->size; + for (i=0; i<pkt_cnt; i++) { + ssize_t rv; + + ecp_pld_set_type(pld_buf, pld_size, mtype); + ecp_pld_set_frag(pld_buf, pld_size, i, pkt_cnt, frag_size); + msg_buf = ecp_pld_get_msg(pld_buf, pld_size); + + if ((i == pkt_cnt - 1) && frag_size_final) frag_size = frag_size_final; + memcpy(msg_buf, msg, frag_size); + msg += frag_size; + nonce = nonce_start + i; + + rv = ecp_pld_send_wnonce(conn, packet, payload, ECP_SIZE_PLD(frag_size, mtype), 0, &nonce); + if (rv < 0) return rv; + } + + return msg_size; +} + +ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size) { + ECPRBConn *_conn = NULL; + ECPFragIter *iter = NULL; + unsigned char *msg; + unsigned char frag_cnt, frag_tot; + uint16_t frag_size; + size_t hdr_size, msg_size; + size_t buf_offset; + int rv; + + _conn = ecp_rbuf_get_rbconn(conn); + if (conn) iter = ecp_frag_iter_get(_conn); + if (iter == NULL) ECP_ERR_ITER; + + rv = ecp_pld_get_frag(payload, pld_size, &frag_cnt, &frag_tot, &frag_size); + if (rv) return ECP_ERR; + + msg = ecp_pld_get_msg(payload, pld_size); + if (msg == NULL) return ECP_ERR; + hdr_size = msg - payload; + + msg_size = pld_size - hdr_size; + if (msg_size == 0) return ECP_ERR; + + if (iter->pld_size && (iter->seq + frag_cnt != seq)) ecp_frag_iter_reset(iter); + + if (iter->pld_size == 0) { + iter->seq = seq - frag_cnt; + iter->frag_cnt = 0; + } + + mtype &= ~ECP_MTYPE_FLAG_FRAG; + buf_offset = ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) + frag_size * frag_cnt; + if (buf_offset + msg_size > iter->buf_size) return ECP_ERR_SIZE; + memcpy(iter->buffer + buf_offset, msg, msg_size); + + if (frag_cnt == 0) { + if (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) > iter->buf_size) return ECP_ERR_SIZE; + + iter->buffer[0] = mtype; + if (ECP_SIZE_MT_FLAG(mtype)) { + memcpy(iter->buffer + ECP_SIZE_MTYPE, payload + ECP_SIZE_MTYPE, ECP_SIZE_MT_FLAG(mtype)); + } + msg_size += ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype); + } + + iter->frag_cnt++; + iter->pld_size += msg_size; + if (iter->frag_cnt == frag_tot) { + ecp_pld_handle_one(conn, iter->seq, iter->buffer, iter->pld_size, NULL); + ecp_frag_iter_reset(iter); + } + + return pld_size; +} diff --git a/ecp/src/ecp/ext/frag.h b/ecp/src/ecp/ext/frag.h new file mode 100644 index 0000000..1400c1d --- /dev/null +++ b/ecp/src/ecp/ext/frag.h @@ -0,0 +1,13 @@ +typedef struct ECPFragIter { + ecp_seq_t seq; + unsigned char frag_cnt; + unsigned char *buffer; + size_t buf_size; + size_t pld_size; +} ECPFragIter; + +int ecp_frag_iter_init(ECPRBConn *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size); +ECPFragIter *ecp_frag_iter_get(ECPRBConn *conn); +void ecp_frag_iter_reset(ECPFragIter *iter); +ssize_t ecp_msg_frag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload); +ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size);
\ No newline at end of file |