summaryrefslogtreecommitdiff
path: root/code/esp32/components/eos
diff options
context:
space:
mode:
Diffstat (limited to 'code/esp32/components/eos')
-rw-r--r--code/esp32/components/eos/include/sock.h18
-rw-r--r--code/esp32/components/eos/sock.c155
2 files changed, 173 insertions, 0 deletions
diff --git a/code/esp32/components/eos/include/sock.h b/code/esp32/components/eos/include/sock.h
new file mode 100644
index 0000000..7e937cb
--- /dev/null
+++ b/code/esp32/components/eos/include/sock.h
@@ -0,0 +1,18 @@
+#include <stdint.h>
+
+#define EOS_SOCK_MTYPE_PKT 0
+#define EOS_SOCK_MTYPE_OPEN_DGRAM 1
+#define EOS_SOCK_MTYPE_CLOSE 127
+
+#define EOS_SOCK_MAX_SOCK 2
+
+#define EOS_SOCK_SIZE_UDP_HDR 8
+
+#define EOS_IPv4_ADDR_SIZE 4
+
+typedef struct EOSNetAddr {
+ unsigned char host[EOS_IPv4_ADDR_SIZE];
+ uint16_t port;
+} EOSNetAddr;
+
+void eos_sock_init(void); \ No newline at end of file
diff --git a/code/esp32/components/eos/sock.c b/code/esp32/components/eos/sock.c
new file mode 100644
index 0000000..2ccfb65
--- /dev/null
+++ b/code/esp32/components/eos/sock.c
@@ -0,0 +1,155 @@
+#include <stdlib.h>
+#include <stdint.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 <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 "net.h"
+#include "sock.h"
+
+static const char *TAG = "EOS";
+static SemaphoreHandle_t mutex;
+static int _socks[EOS_SOCK_MAX_SOCK];
+
+static int t_open_dgram(void) {
+ struct sockaddr_in _myaddr;
+ int sock;
+
+ sock = socket(PF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) return sock;
+
+ memset((char *)&_myaddr, 0, sizeof(_myaddr));
+ _myaddr.sin_family = AF_INET;
+ _myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ _myaddr.sin_port = htons(3000);
+
+ int rv = bind(sock, (struct sockaddr *)&_myaddr, sizeof(_myaddr));
+ if (rv < 0) {
+ close(sock);
+ return rv;
+ }
+ return sock;
+}
+
+static void t_close(int sock) {
+ close(sock);
+}
+
+static ssize_t t_sendto(int sock, 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(sock, msg, msg_size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
+}
+
+static ssize_t t_recvfrom(int sock, 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(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 sock_receiver(void *pvParameters) {
+ EOSNetAddr addr;
+ unsigned char buffer[EOS_NET_SIZE_BUF];
+ uint8_t esock = (uint8_t)pvParameters;
+ int sock = _socks[esock-1];
+
+ buffer[0] = EOS_SOCK_MTYPE_PKT;
+ buffer[1] = esock;
+ do {
+ ssize_t rv = t_recvfrom(sock, buffer+EOS_SOCK_SIZE_UDP_HDR, EOS_NET_SIZE_BUF-EOS_SOCK_SIZE_UDP_HDR, &addr);
+ if (rv < 0) {
+ sock = 0;
+ ESP_LOGE(TAG, "UDP RECV ERR:%d", rv);
+ continue;
+ }
+ memcpy(buffer+2, addr.host, sizeof(addr.host));
+ memcpy(buffer+2+sizeof(addr.host), &addr.port, sizeof(addr.port));
+ eos_net_send(EOS_NET_MTYPE_SOCK, buffer, rv+EOS_SOCK_SIZE_UDP_HDR, 0);
+ } while(sock);
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ _socks[esock-1] = 0;
+ xSemaphoreGive(mutex);
+ vTaskDelete(NULL);
+}
+
+static void sock_handler(unsigned char type, unsigned char *buffer, uint16_t size) {
+ EOSNetAddr addr;
+ unsigned char ret[2];
+ uint8_t esock;
+ int sock, i;
+
+ if (size < 1) return;
+
+ switch(buffer[0]) {
+ case EOS_SOCK_MTYPE_PKT:
+ if (size < EOS_SOCK_SIZE_UDP_HDR) return;
+ sock = _socks[buffer[1]-1];
+ memcpy(addr.host, buffer+2, sizeof(addr.host));
+ memcpy(&addr.port, buffer+2+sizeof(addr.host), sizeof(addr.port));
+ t_sendto(sock, buffer+EOS_SOCK_SIZE_UDP_HDR, size-EOS_SOCK_SIZE_UDP_HDR, &addr);
+ break;
+ case EOS_SOCK_MTYPE_OPEN_DGRAM:
+ sock = t_open_dgram();
+ esock = 0;
+ if (sock > 0) {
+ xSemaphoreTake(mutex, portMAX_DELAY);
+ for (i=0; i<EOS_SOCK_MAX_SOCK; i++) {
+ if (_socks[i] == 0) {
+ esock = i+1;
+ _socks[i] = sock;
+ }
+ }
+ xSemaphoreGive(mutex);
+ }
+ ret[0] = EOS_SOCK_MTYPE_OPEN_DGRAM;
+ ret[1] = esock;
+ // xTaskCreatePinnedToCore(&sock_receiver, "sock_receiver", 2048, NULL, EOS_IRQ_PRIORITY_UDP_RCVR, NULL, 1);
+ xTaskCreate(&sock_receiver, "sock_receiver", 2048, (void *)esock, EOS_IRQ_PRIORITY_UDP_RCVR, NULL);
+ eos_net_send(EOS_NET_MTYPE_SOCK, ret, 2, 0);
+ break;
+ case EOS_SOCK_MTYPE_CLOSE:
+ if (size < 2) return;
+ sock = _socks[buffer[1]-1];
+ t_close(sock);
+ break;
+ default:
+ break;
+ }
+}
+
+void eos_sock_init(void) {
+ mutex = xSemaphoreCreateBinary();
+ xSemaphoreGive(mutex);
+ eos_net_set_handler(EOS_NET_MTYPE_SOCK, sock_handler);
+} \ No newline at end of file