#define DBG_TAG "[LFT_INET]" #include "private/lftpd_inet.h" #include "dbg_log.h" #include "net_socket.h" #include int lftpd_inet_listen(int port) { int s = net_socket(NET_AF_INET, NET_SOCK_STREAM, 0); if (s < 0) { DBG_ERROR("error creating listener socket"); return -1; } struct net_sockaddr_in addr; addr.sin_family = NET_AF_INET; addr.sin_port = net_htons((uint16_t)port); addr.sin_addr.s_addr = 0; if (net_bind(s, (struct net_sockaddr *)&addr, sizeof(addr)) < 0) { DBG_ERROR("error binding listener port %d", port); net_close(s); return -1; } if (net_listen(s, 0) < 0) { DBG_ERROR("error listening on socket"); net_close(s); return -1; } return s; } int lftpd_inet_listen_multi(int port, int backlog) { int s = net_socket(NET_AF_INET, NET_SOCK_STREAM, 0); if (s < 0) { DBG_ERROR("error creating multi listener socket"); return -1; } struct net_sockaddr_in addr; addr.sin_family = NET_AF_INET; addr.sin_port = net_htons((uint16_t)port); addr.sin_addr.s_addr = 0; if (net_bind(s, (struct net_sockaddr *)&addr, sizeof(addr)) < 0) { DBG_ERROR("error binding multi listener port %d", port); net_close(s); return -1; } if (net_listen(s, backlog) < 0) { DBG_ERROR("error listening on multi socket"); net_close(s); return -1; } return s; } int lftpd_inet_get_socket_port(int socket) { struct net_sockaddr_in addr; int addrlen = sizeof(addr); if (net_getsockname(socket, (struct net_sockaddr *)&addr, &addrlen) < 0) { DBG_ERROR("error getting socket port number"); return -1; } return (int)net_ntohs(addr.sin_port); } int lftpd_inet_accept(int socket) { while (1) { int s = net_accept(socket, NULL, NULL); if (s >= 0) { return s; } vTaskDelay(pdMS_TO_TICKS(10)); } } int lftpd_inet_read_line(int socket, char *buffer, size_t buffer_len) { memset(buffer, 0, buffer_len); int total_read_len = 0; while (total_read_len < (int)buffer_len) { int read_len = net_recv(socket, buffer + total_read_len, buffer_len - total_read_len - 1, 0); if (read_len == 0) { return -1; } if (read_len < 0) { return read_len; } total_read_len += read_len; char *p = strstr(buffer, "\r\n"); if (p != NULL) { *p = '\0'; return 0; } } return -1; } int lftpd_inet_write_string(int socket, const char *message) { const char *p = message; int length = (int)strlen(message); while (length > 0) { int write_len = net_send(socket, p, length, 0); if (write_len < 0) { DBG_ERROR("write error"); return write_len; } p += write_len; length -= write_len; } return 0; } int lftpd_inet_write(int socket, const void *buf, int len) { const char *p = (const char *)buf; int remaining = len; while (remaining > 0) { int n = net_send(socket, p, remaining, 0); if (n < 0) { return n; } p += n; remaining -= n; } return len; } int lftpd_inet_read(int socket, void *buf, int len) { int n = net_recv(socket, buf, len, 0); return n; } int lftpd_inet_close(int socket) { return net_close(socket); }