#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "eos.h" #include "net.h" #include "sock.h" static const char *TAG = "EOS SOCK"; 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; uint8_t esock = (uint8_t)pvParameters; int sock = _socks[esock-1]; unsigned char *buf; do { ssize_t rv; buf = eos_net_alloc(); rv = t_recvfrom(sock, buf+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; } buf[0] = EOS_SOCK_MTYPE_PKT; buf[1] = esock; memcpy(buf+2, addr.host, sizeof(addr.host)); memcpy(buf+2+sizeof(addr.host), &addr.port, sizeof(addr.port)); eos_net_send(EOS_NET_MTYPE_SOCK, buf, 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; uint8_t esock; int sock, i; unsigned char *rbuf; 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