diff options
author | Uros Majstorovic <majstor@majstor.org> | 2019-10-19 19:40:32 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2019-10-19 19:40:32 +0200 |
commit | 3cbb9793bf5645f400545aeef904a48fe5dca64c (patch) | |
tree | a961a55b16d841d9dad8a573f0f6ec2514f8bd51 /code/fe310/eos/sock.c | |
parent | 97968cb17dee6d1d0e68149fe2fb71362cdc5851 (diff) |
network sockets added
Diffstat (limited to 'code/fe310/eos/sock.c')
-rw-r--r-- | code/fe310/eos/sock.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/code/fe310/eos/sock.c b/code/fe310/eos/sock.c new file mode 100644 index 0000000..b217b43 --- /dev/null +++ b/code/fe310/eos/sock.c @@ -0,0 +1,102 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include "eos.h" +#include "event.h" +#include "net.h" + +#include "sock.h" + +static eos_sock_fptr_t sock_handler[EOS_SOCK_MAX_SOCK]; +static uint16_t sock_handler_flags_buf_free = 0; +static uint16_t sock_handler_flags_buf_acq = 0; + +static void sock_handler_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + if (buffer[0] == EOS_SOCK_MTYPE_PKT) { + uint8_t sock = buffer[1]; + if (sock && (sock <= EOS_SOCK_MAX_SOCK)) { + sock--; + } else { + eos_evtq_bad_handler(type, buffer, len); + eos_net_free(buffer, 0); + return; + } + uint16_t buf_free = ((uint16_t)1 << sock) & sock_handler_flags_buf_free; + uint16_t buf_acq = ((uint16_t)1 << sock) & sock_handler_flags_buf_acq; + if (buf_free) { + eos_net_free(buffer, buf_acq); + buffer = NULL; + len = 0; + } + + sock_handler[sock](buffer, len); + + if (buf_free && buf_acq) eos_net_release(); + } +} + +void eos_sock_init(void) { + eos_net_set_handler(EOS_NET_MTYPE_SOCK, sock_handler_evt, 0); +} + +int eos_sock_open_udp(void) { + unsigned char type = EOS_SOCK_MTYPE_OPEN_DGRAM; + unsigned char *buffer = eos_net_alloc(); + uint16_t buf_size; + int rv, sock; + + buffer[0] = type; + rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, 1, 0); + if (rv) return rv; + + eos_evtq_get(EOS_NET_MTYPE_SOCK, &type, 1, &buffer, &buf_size); + if (buf_size < 2) { + eos_net_free(buffer, 0); + return EOS_ERR_NET; + } + + sock = buffer[1]; + eos_net_free(buffer, 1); + + return sock; +} + +void eos_sock_close(int sock) { + unsigned char *buffer = eos_net_alloc(); + buffer[0] = EOS_SOCK_MTYPE_CLOSE; + buffer[1] = sock; + eos_net_send(EOS_NET_MTYPE_SOCK, buffer, 2, 1); +} + +int eos_sock_sendto(int sock, unsigned char *buffer, uint16_t size, unsigned char more, EOSNetAddr *addr) { + unsigned char type = EOS_NET_MTYPE_SOCK; + + buffer[0] = EOS_SOCK_MTYPE_PKT; + buffer[1] = sock; + memcpy(buffer+2, addr->host, sizeof(addr->host)); + memcpy(buffer+2+sizeof(addr->host), &addr->port, sizeof(addr->port)); + return eos_net_send(type, buffer, size, more); +} + +void eos_sock_getfrom(unsigned char *buffer, EOSNetAddr *addr) { + memcpy(addr->host, buffer+2, sizeof(addr->host)); + memcpy(&addr->port, buffer+2+sizeof(addr->host), sizeof(addr->port)); +} + + +void eos_sock_set_handler(int sock, eos_sock_fptr_t handler, uint8_t flags) { + if (sock && (sock <= EOS_SOCK_MAX_SOCK)) { + sock--; + } else { + return; + } + if (flags) { + uint16_t flag = (uint16_t)1 << sock; + if (flags & EOS_NET_FLAG_BUF_FREE) sock_handler_flags_buf_free |= flag; + if (flags & EOS_NET_FLAG_BUF_ACQ) sock_handler_flags_buf_acq |= flag; + } + sock_handler[sock] = handler; +} + + |