3.3.7
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
Server.cpp - Server class for Raspberry Pi
|
||||
Copyright (c) 2016 Hristo Gochkov All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "NetworkServer.h"
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/netdb.h>
|
||||
|
||||
#undef write
|
||||
#undef close
|
||||
|
||||
int NetworkServer::setTimeout(uint32_t seconds) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = seconds;
|
||||
tv.tv_usec = 0;
|
||||
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval));
|
||||
}
|
||||
|
||||
NetworkClient NetworkServer::available() {
|
||||
return accept();
|
||||
}
|
||||
|
||||
NetworkClient NetworkServer::accept() {
|
||||
if (!_listening) {
|
||||
return NetworkClient();
|
||||
}
|
||||
int client_sock;
|
||||
if (_accepted_sockfd >= 0) {
|
||||
client_sock = _accepted_sockfd;
|
||||
_accepted_sockfd = -1;
|
||||
} else {
|
||||
#if CONFIG_LWIP_IPV6
|
||||
struct sockaddr_in6 _client;
|
||||
int cs = sizeof(struct sockaddr_in6);
|
||||
#else
|
||||
struct sockaddr_in _client;
|
||||
int cs = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
#ifdef ESP_IDF_VERSION_MAJOR
|
||||
client_sock = lwip_accept(sockfd, (struct sockaddr *)&_client, (socklen_t *)&cs);
|
||||
#else
|
||||
client_sock = lwip_accept_r(sockfd, (struct sockaddr *)&_client, (socklen_t *)&cs);
|
||||
#endif
|
||||
}
|
||||
if (client_sock >= 0) {
|
||||
int val = 1;
|
||||
if (setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&val, sizeof(int)) == ESP_OK) {
|
||||
val = _noDelay;
|
||||
if (setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(int)) == ESP_OK) {
|
||||
return NetworkClient(client_sock);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NetworkClient();
|
||||
}
|
||||
|
||||
void NetworkServer::begin(uint16_t port) {
|
||||
begin(port, 1);
|
||||
}
|
||||
|
||||
void NetworkServer::begin(uint16_t port, int enable) {
|
||||
if (_listening) {
|
||||
return;
|
||||
}
|
||||
if (port) {
|
||||
_port = port;
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
struct sockaddr_in6 server;
|
||||
sockfd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) {
|
||||
return;
|
||||
}
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
|
||||
server.sin6_family = AF_INET6;
|
||||
if (_addr.type() == IPv4) {
|
||||
memcpy(server.sin6_addr.s6_addr + 11, (uint8_t *)&_addr[0], 4);
|
||||
server.sin6_addr.s6_addr[10] = 0xFF;
|
||||
server.sin6_addr.s6_addr[11] = 0xFF;
|
||||
} else {
|
||||
memcpy(server.sin6_addr.s6_addr, (uint8_t *)&_addr[0], 16);
|
||||
}
|
||||
memset(server.sin6_addr.s6_addr, 0x0, 16);
|
||||
server.sin6_port = htons(_port);
|
||||
#else
|
||||
struct sockaddr_in server;
|
||||
memset(&server, 0x0, sizeof(sockaddr_in));
|
||||
server.sin_family = AF_INET;
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) {
|
||||
return;
|
||||
}
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
|
||||
memcpy((uint8_t *)&(server.sin_addr.s_addr), (uint8_t *)&_addr[0], 4);
|
||||
server.sin_port = htons(_port);
|
||||
#endif
|
||||
if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) {
|
||||
return;
|
||||
}
|
||||
if (listen(sockfd, _max_clients) < 0) {
|
||||
return;
|
||||
}
|
||||
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
||||
_listening = true;
|
||||
_noDelay = false;
|
||||
_accepted_sockfd = -1;
|
||||
}
|
||||
|
||||
void NetworkServer::setNoDelay(bool nodelay) {
|
||||
_noDelay = nodelay;
|
||||
}
|
||||
|
||||
bool NetworkServer::getNoDelay() {
|
||||
return _noDelay;
|
||||
}
|
||||
|
||||
bool NetworkServer::hasClient() {
|
||||
if (_accepted_sockfd >= 0) {
|
||||
return true;
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
struct sockaddr_in6 _client;
|
||||
int cs = sizeof(struct sockaddr_in6);
|
||||
#else
|
||||
struct sockaddr _client;
|
||||
int cs = sizeof(struct sockaddr);
|
||||
#endif
|
||||
#ifdef ESP_IDF_VERSION_MAJOR
|
||||
_accepted_sockfd = lwip_accept(sockfd, (struct sockaddr *)&_client, (socklen_t *)&cs);
|
||||
#else
|
||||
_accepted_sockfd = lwip_accept_r(sockfd, (struct sockaddr *)&_client, (socklen_t *)&cs);
|
||||
#endif
|
||||
if (_accepted_sockfd >= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkServer::end() {
|
||||
#ifdef ESP_IDF_VERSION_MAJOR
|
||||
lwip_close(sockfd);
|
||||
#else
|
||||
lwip_close_r(sockfd);
|
||||
#endif
|
||||
sockfd = -1;
|
||||
_listening = false;
|
||||
}
|
||||
|
||||
void NetworkServer::close() {
|
||||
end();
|
||||
}
|
||||
|
||||
void NetworkServer::stop() {
|
||||
end();
|
||||
}
|
||||
Reference in New Issue
Block a user