diff options
author | Uros Majstorovic <majstor@majstor.org> | 2019-12-04 06:13:26 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2019-12-04 06:13:26 +0100 |
commit | 5454acdb6e04aa454989b78a2f20be2c25740585 (patch) | |
tree | d296067e23c50070b06e543193efb1536eb11822 /code | |
parent | 4c28fb525edc64fa16c6c3bf10929dca65d9c77c (diff) |
esp32: added sock interface
Diffstat (limited to 'code')
-rw-r--r-- | code/esp32/components/eos/include/sock.h | 18 | ||||
-rw-r--r-- | code/esp32/components/eos/sock.c | 155 |
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 |