diff --git a/source_modules/hermes_source/src/hermes.h b/source_modules/hermes_source/src/hermes.h index 5b48bb02..96755243 100644 --- a/source_modules/hermes_source/src/hermes.h +++ b/source_modules/hermes_source/src/hermes.h @@ -1,5 +1,5 @@ #pragma once -#include "net.h" +#include #include #include #include diff --git a/source_modules/hermes_source/src/net.cpp b/source_modules/hermes_source/src/net.cpp deleted file mode 100644 index 8f62f511..00000000 --- a/source_modules/hermes_source/src/net.cpp +++ /dev/null @@ -1,403 +0,0 @@ -#include "net.h" -#include -#include - -#ifdef _WIN32 -#define WOULD_BLOCK (WSAGetLastError() == WSAEWOULDBLOCK) -#else -#define WOULD_BLOCK (errno == EWOULDBLOCK) -#endif - -namespace net { - bool _init = false; - - // === Private functions === - - void init() { - if (_init) { return; } -#ifdef _WIN32 - // Initialize WinSock2 - WSADATA wsa; - if (WSAStartup(MAKEWORD(2, 2), &wsa)) { - throw std::runtime_error("Could not initialize WinSock2"); - return; - } -#else - // Disable SIGPIPE to avoid closing when the remote host disconnects - signal(SIGPIPE, SIG_IGN); -#endif - _init = true; - } - - bool queryHost(uint32_t* addr, std::string host) { - hostent* ent = gethostbyname(host.c_str()); - if (!ent || !ent->h_addr_list[0]) { return false; } - *addr = *(uint32_t*)ent->h_addr_list[0]; - return true; - } - - void closeSocket(SockHandle_t sock) { -#ifdef _WIN32 - shutdown(sock, SD_BOTH); - closesocket(sock); -#else - shutdown(sock, SHUT_RDWR); - close(sock); -#endif - } - - void setNonblocking(SockHandle_t sock) { -#ifdef _WIN32 - u_long enabled = 1; - ioctlsocket(sock, FIONBIO, &enabled); -#else - fcntl(sock, F_SETFL, O_NONBLOCK); -#endif - } - - // === Address functions === - - Address::Address() { - memset(&addr, 0, sizeof(addr)); - } - - Address::Address(const std::string& host, int port) { - // Initialize WSA if needed - init(); - - // Lookup host - hostent* ent = gethostbyname(host.c_str()); - if (!ent || !ent->h_addr_list[0]) { - throw std::runtime_error("Unknown host"); - } - - // Build address - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = *(uint32_t*)ent->h_addr_list[0]; - addr.sin_port = htons(port); - } - - Address::Address(IP_t ip, int port) { - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(ip); - addr.sin_port = htons(port); - } - - std::string Address::getIPStr() { - char buf[128]; - IP_t ip = getIP(); - sprintf(buf, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); - return buf; - } - - IP_t Address::getIP() { - return htonl(addr.sin_addr.s_addr); - } - - void Address::setIP(IP_t ip) { - addr.sin_addr.s_addr = htonl(ip); - } - - int Address::getPort() { - return htons(addr.sin_port); - } - - void Address::setPort(int port) { - addr.sin_port = htons(port); - } - - // === Socket functions === - - Socket::Socket(SockHandle_t sock, const Address* raddr) { - this->sock = sock; - if (raddr) { - this->raddr = new Address(*raddr); - } - } - - Socket::~Socket() { - close(); - if (raddr) { delete raddr; } - } - - void Socket::close() { - if (!open) { return; } - open = false; - closeSocket(sock); - } - - bool Socket::isOpen() { - return open; - } - - SocketType Socket::type() { - return raddr ? SOCKET_TYPE_UDP : SOCKET_TYPE_TCP; - } - - int Socket::send(const uint8_t* data, size_t len, const Address* dest) { - return sendto(sock, (const char*)data, len, 0, (sockaddr*)(dest ? &dest->addr : (raddr ? &raddr->addr : NULL)), sizeof(sockaddr_in)); - } - - int Socket::sendstr(const std::string& str, const Address* dest) { - return send((const uint8_t*)str.c_str(), str.length(), dest); - } - - int Socket::recv(uint8_t* data, size_t maxLen, bool forceLen, int timeout, Address* dest) { - // Create FD set - fd_set set; - FD_ZERO(&set); - FD_SET(sock, &set); - - // Define timeout - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = timeout * 1000; - - int read = 0; - bool blocking = (timeout != NONBLOCKING); - do { - // Wait for data or error if - if (blocking) { - int err = select(sock+1, &set, NULL, &set, (timeout > 0) ? &tv : NULL); - if (err <= 0) { return err; } - } - - // Receive - int addrLen = sizeof(sockaddr_in); - int err = ::recvfrom(sock, (char*)&data[read], maxLen - read, 0,(sockaddr*)(dest ? &dest->addr : NULL), (socklen_t*)(dest ? &addrLen : NULL)); - if (err <= 0 && !WOULD_BLOCK) { - close(); - return err; - } - read += err; - } - while (blocking && forceLen && read < maxLen); - return read; - } - - int Socket::recvline(std::string& str, int maxLen, int timeout, Address* dest) { - // Disallow nonblocking mode - if (timeout < 0) { return -1; } - - str.clear(); - int read = 0; - while (true) { - char c; - int err = recv((uint8_t*)&c, 1, false, timeout, dest); - if (err <= 0) { return err; } - if (c == '\n') { break; } - str += c; - read++; - if (maxLen && read >= maxLen) { break; } - } - return read; - } - - // === Listener functions === - - Listener::Listener(SockHandle_t sock) { - this->sock = sock; - } - - Listener::~Listener() { - stop(); - } - - void Listener::stop() { - closeSocket(sock); - open = false; - } - - bool Listener::listening() { - return open; - } - - std::shared_ptr Listener::accept(Address* dest, int timeout) { - // Create FD set - fd_set set; - FD_ZERO(&set); - FD_SET(sock, &set); - - // Define timeout - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = timeout * 1000; - - // Wait for data or error - if (timeout != NONBLOCKING) { - int err = select(sock+1, &set, NULL, &set, (timeout > 0) ? &tv : NULL); - if (err <= 0) { return NULL; } - } - - // Accept - int addrLen = sizeof(sockaddr_in); - SockHandle_t s = ::accept(sock, (sockaddr*)(dest ? &dest->addr : NULL), (socklen_t*)(dest ? &addrLen : NULL)); - if ((int)s < 0) { - if (!WOULD_BLOCK) { stop(); } - return NULL; - } - - // Enable nonblocking mode - setNonblocking(s); - - return std::make_shared(s); - } - - // === Creation functions === - - std::map listInterfaces() { - // Init library if needed - init(); - - std::map ifaces; -#ifdef _WIN32 - // Pre-allocate buffer - ULONG size = sizeof(IP_ADAPTER_ADDRESSES); - PIP_ADAPTER_ADDRESSES addresses = (PIP_ADAPTER_ADDRESSES)malloc(size); - - // Reallocate to real size - if (GetAdaptersAddresses(AF_INET, 0, NULL, addresses, &size) == ERROR_BUFFER_OVERFLOW) { - addresses = (PIP_ADAPTER_ADDRESSES)realloc(addresses, size); - if (GetAdaptersAddresses(AF_INET, 0, NULL, addresses, &size)) { - throw std::exception("Could not list network interfaces"); - } - } - - // Save data - std::wstring_convert> utfConv; - for (auto iface = addresses; iface; iface = iface->Next) { - InterfaceInfo info; - auto ip = iface->FirstUnicastAddress; - if (!ip || ip->Address.lpSockaddr->sa_family != AF_INET) { continue; } - info.address = ntohl(*(uint32_t*)&ip->Address.lpSockaddr->sa_data[2]); - info.netmask = ~((1 << (32 - ip->OnLinkPrefixLength)) - 1); - info.broadcast = info.address | (~info.netmask); - ifaces[utfConv.to_bytes(iface->FriendlyName)] = info; - } - - // Free tables - free(addresses); -#else - // Get iface list - struct ifaddrs* addresses = NULL; - getifaddrs(&addresses); - - // Save data - for (auto iface = addresses; iface; iface = iface->ifa_next) { - if (iface->ifa_addr->sa_family != AF_INET) { continue; } - InterfaceInfo info; - info.address = ntohl(*(uint32_t*)&iface->ifa_addr->sa_data[2]); - info.netmask = ntohl(*(uint32_t*)&iface->ifa_netmask->sa_data[2]); - info.broadcast = info.address | (~info.netmask); - ifaces[iface->ifa_name] = info; - } - - // Free iface list - freeifaddrs(addresses); -#endif - - return ifaces; - } - - std::shared_ptr listen(const Address& addr) { - // Init library if needed - init(); - - // Create socket - SockHandle_t s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - // TODO: Support non-blockign mode - -#ifndef _WIN32 - // Allow port reusing if the app was killed or crashed - // and the socket is stuck in TIME_WAIT state. - // This option has a different meaning on Windows, - // so we use it only for non-Windows systems - int enable = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) { - closeSocket(s); - throw std::runtime_error("Could not configure socket"); - return NULL; - } -#endif - - // Bind socket to the port - if (bind(s, (sockaddr*)&addr.addr, sizeof(sockaddr_in))) { - closeSocket(s); - throw std::runtime_error("Could not bind socket"); - return NULL; - } - - // Enable listening - if (::listen(s, SOMAXCONN) != 0) { - throw std::runtime_error("Could start listening for connections"); - return NULL; - } - - // Enable nonblocking mode - setNonblocking(s); - - // Return listener class - return std::make_shared(s); - } - - std::shared_ptr listen(std::string host, int port) { - return listen(Address(host, port)); - } - - std::shared_ptr connect(const Address& addr) { - // Init library if needed - init(); - - // Create socket - SockHandle_t s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - // Connect to server - if (::connect(s, (sockaddr*)&addr.addr, sizeof(sockaddr_in))) { - closeSocket(s); - throw std::runtime_error("Could not connect"); - return NULL; - } - - // Enable nonblocking mode - setNonblocking(s); - - // Return socket class - return std::make_shared(s); - } - - std::shared_ptr connect(std::string host, int port) { - return connect(Address(host, port)); - } - - std::shared_ptr openudp(const Address& raddr, const Address& laddr) { - // Init library if needed - init(); - - // Create socket - SockHandle_t s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - - // Bind socket to local port - if (bind(s, (sockaddr*)&laddr.addr, sizeof(sockaddr_in))) { - closeSocket(s); - throw std::runtime_error("Could not bind socket"); - return NULL; - } - - // Return socket class - return std::make_shared(s, &raddr); - } - - std::shared_ptr openudp(std::string rhost, int rport, const Address& laddr) { - return openudp(Address(rhost, rport), laddr); - } - - std::shared_ptr openudp(const Address& raddr, std::string lhost, int lport) { - return openudp(raddr, Address(lhost, lport)); - } - - std::shared_ptr openudp(std::string rhost, int rport, std::string lhost, int lport) { - return openudp(Address(rhost, rport), Address(lhost, lport)); - } -} \ No newline at end of file diff --git a/source_modules/hermes_source/src/net.h b/source_modules/hermes_source/src/net.h deleted file mode 100644 index a35a6fbb..00000000 --- a/source_modules/hermes_source/src/net.h +++ /dev/null @@ -1,281 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -namespace net { -#ifdef _WIN32 - typedef SOCKET SockHandle_t; - typedef int socklen_t; -#else - typedef int SockHandle_t; -#endif - typedef uint32_t IP_t; - - class Socket; - class Listener; - - struct InterfaceInfo { - IP_t address; - IP_t netmask; - IP_t broadcast; - }; - - class Address { - friend Socket; - friend Listener; - public: - /** - * Default constructor. Corresponds to 0.0.0.0:0. - */ - Address(); - - /** - * Do not instantiate this class manually. Use the provided functions. - * @param host Hostname or IP. - * @param port TCP/UDP port. - */ - Address(const std::string& host, int port); - - /** - * Do not instantiate this class manually. Use the provided functions. - * @param ip IP in host byte order. - * @param port TCP/UDP port. - */ - Address(IP_t ip, int port); - - /** - * Get the IP address. - * @return IP address in standard string format. - */ - std::string getIPStr(); - - /** - * Get the IP address. - * @return IP address in host byte order. - */ - IP_t getIP(); - - /** - * Set the IP address. - * @param ip IP address in host byte order. - */ - void setIP(IP_t ip); - - /** - * Get the TCP/UDP port. - * @return TCP/UDP port number. - */ - int getPort(); - - /** - * Set the TCP/UDP port. - * @param port TCP/UDP port number. - */ - void setPort(int port); - - struct sockaddr_in addr; - }; - - enum { - NO_TIMEOUT = -1, - NONBLOCKING = 0 - }; - - enum SocketType { - SOCKET_TYPE_TCP, - SOCKET_TYPE_UDP - }; - - class Socket { - public: - /** - * Do not instantiate this class manually. Use the provided functions. - */ - Socket(SockHandle_t sock, const Address* raddr = NULL); - ~Socket(); - - /** - * Close socket. The socket can no longer be used after this. - */ - void close(); - - /** - * Check if the socket is open. - * @return True if open, false if closed. - */ - bool isOpen(); - - /** - * Get socket type. Either TCP or UDP. - * @return Socket type. - */ - SocketType type(); - - /** - * Send data on socket. - * @param data Data to be sent. - * @param len Number of bytes to be sent. - * @param dest Destination address. NULL to use the default remote address. - * @return Number of bytes sent. - */ - int send(const uint8_t* data, size_t len, const Address* dest = NULL); - - /** - * Send string on socket. Terminating NULL byte is not sent, include one in the string if you need it. - * @param str String to be sent. - * @param dest Destination address. NULL to use the default remote address. - * @return Number of bytes sent. - */ - int sendstr(const std::string& str, const Address* dest = NULL); - - /** - * Receive data from socket. - * @param data Buffer to read the data into. - * @param maxLen Maximum number of bytes to read. - * @param forceLen Read the maximum number of bytes even if it requires multiple receive operations. - * @param timeout Timeout in milliseconds. Use NO_TIMEOUT or NONBLOCKING here if needed. - * @param dest Destination address. If multiple packets, this will contain the address of the last one. NULL if not used. - * @return Number of bytes read. 0 means timed out or closed. -1 means would block or error. - */ - int recv(uint8_t* data, size_t maxLen, bool forceLen = false, int timeout = NO_TIMEOUT, Address* dest = NULL); - - /** - * Receive line from socket. - * @param str String to read the data into. - * @param maxLen Maximum line length allowed, 0 for no limit. - * @param timeout Timeout in milliseconds. Use NO_TIMEOUT or NONBLOCKING here if needed. - * @param dest Destination address. If multiple packets, this will contain the address of the last one. NULL if not used. - * @return Length of the returned string. 0 means timed out or closed. -1 means would block or error. - */ - int recvline(std::string& str, int maxLen = 0, int timeout = NO_TIMEOUT, Address* dest = NULL); - - private: - Address* raddr = NULL; - SockHandle_t sock; - bool open = true; - - }; - - class Listener { - public: - /** - * Do not instantiate this class manually. Use the provided functions. - */ - Listener(SockHandle_t sock); - ~Listener(); - - /** - * Stop listening. The listener can no longer be used after this. - */ - void stop(); - - /** - * CHeck if the listener is still listening. - * @return True if listening, false if not. - */ - bool listening(); - - /** - * Accept connection. - * @param timeout Timeout in milliseconds. Use NO_TIMEOUT or NONBLOCKING here if needed. - * @return Socket of the connection. NULL means timed out, would block or closed. - */ - std::shared_ptr accept(Address* dest = NULL, int timeout = NO_TIMEOUT); - - private: - SockHandle_t sock; - bool open = true; - - }; - - /** - * Get a list of the network interface. - * @return List of network interfaces and their addresses. - */ - std::map listInterfaces(); - - /** - * Create TCP listener. - * @param addr Address to listen on. - * @return Listener instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr listen(const Address& addr); - - /** - * Create TCP listener. - * @param host Hostname or IP to listen on ("0.0.0.0" for Any). - * @param port Port to listen on. - * @return Listener instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr listen(std::string host, int port); - - /** - * Create TCP connection. - * @param addr Remote address. - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr connect(const Address& addr); - - /** - * Create TCP connection. - * @param host Remote hostname or IP address. - * @param port Remote port. - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr connect(std::string host, int port); - - /** - * Create UDP socket. - * @param raddr Remote address. - * @param laddr Local address to bind the socket to. - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr openudp(const Address& raddr, const Address& laddr); - - /** - * Create UDP socket. - * @param rhost Remote hostname or IP address. - * @param rport Remote port. - * @param laddr Local address to bind the socket to. - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr openudp(std::string rhost, int rport, const Address& laddr); - - /** - * Create UDP socket. - * @param raddr Remote address. - * @param lhost Local hostname or IP used to bind the socket (optional, "0.0.0.0" for Any). - * @param lpost Local port used to bind the socket to (optional, 0 to allocate automatically). - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr openudp(const Address& raddr, std::string lhost = "0.0.0.0", int lport = 0); - - /** - * Create UDP socket. - * @param rhost Remote hostname or IP address. - * @param rport Remote port. - * @param lhost Local hostname or IP used to bind the socket (optional, "0.0.0.0" for Any). - * @param lpost Local port used to bind the socket to (optional, 0 to allocate automatically). - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr openudp(std::string rhost, int rport, std::string lhost = "0.0.0.0", int lport = 0); -} \ No newline at end of file diff --git a/source_modules/spectran_http_source/src/net.cpp b/source_modules/spectran_http_source/src/net.cpp deleted file mode 100644 index 13f50c6e..00000000 --- a/source_modules/spectran_http_source/src/net.cpp +++ /dev/null @@ -1,402 +0,0 @@ -#include "net.h" -#include -#include - -#ifdef _WIN32 -#define WOULD_BLOCK (WSAGetLastError() == WSAEWOULDBLOCK) -#else -#define WOULD_BLOCK (errno == EWOULDBLOCK) -#endif - -namespace net { - bool _init = false; - - // === Private functions === - - void init() { - if (_init) { return; } -#ifdef _WIN32 - // Initialize WinSock2 - WSADATA wsa; - if (WSAStartup(MAKEWORD(2, 2), &wsa)) { - throw std::runtime_error("Could not initialize WinSock2"); - return; - } -#else - // Disable SIGPIPE to avoid closing when the remote host disconnects - signal(SIGPIPE, SIG_IGN); -#endif - _init = true; - } - - bool queryHost(uint32_t* addr, std::string host) { - hostent* ent = gethostbyname(host.c_str()); - if (!ent || !ent->h_addr_list[0]) { return false; } - *addr = *(uint32_t*)ent->h_addr_list[0]; - return true; - } - - void closeSocket(SockHandle_t sock) { -#ifdef _WIN32 - shutdown(sock, SD_BOTH); - closesocket(sock); -#else - shutdown(sock, SHUT_RDWR); - close(sock); -#endif - } - - void setNonblocking(SockHandle_t sock) { -#ifdef _WIN32 - u_long enabled = 1; - ioctlsocket(sock, FIONBIO, &enabled); -#else - fcntl(sock, F_SETFL, O_NONBLOCK); -#endif - } - - // === Address functions === - - Address::Address() { - memset(&addr, 0, sizeof(addr)); - } - - Address::Address(const std::string& host, int port) { - // Initialize WSA if needed - init(); - - // Lookup host - hostent* ent = gethostbyname(host.c_str()); - if (!ent || !ent->h_addr_list[0]) { - throw std::runtime_error("Unknown host"); - } - - // Build address - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = *(uint32_t*)ent->h_addr_list[0]; - addr.sin_port = htons(port); - } - - Address::Address(IP_t ip, int port) { - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(ip); - addr.sin_port = htons(port); - } - - std::string Address::getIPStr() { - char buf[128]; - IP_t ip = getIP(); - sprintf(buf, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); - return buf; - } - - IP_t Address::getIP() { - return htonl(addr.sin_addr.s_addr); - } - - void Address::setIP(IP_t ip) { - addr.sin_addr.s_addr = htonl(ip); - } - - int Address::getPort() { - return htons(addr.sin_port); - } - - void Address::setPort(int port) { - addr.sin_port = htons(port); - } - - // === Socket functions === - - Socket::Socket(SockHandle_t sock, const Address* raddr) { - this->sock = sock; - if (raddr) { - this->raddr = new Address(*raddr); - } - } - - Socket::~Socket() { - close(); - if (raddr) { delete raddr; } - } - - void Socket::close() { - if (!open) { return; } - open = false; - closeSocket(sock); - } - - bool Socket::isOpen() { - return open; - } - - SocketType Socket::type() { - return raddr ? SOCKET_TYPE_UDP : SOCKET_TYPE_TCP; - } - - int Socket::send(const uint8_t* data, size_t len, const Address* dest) { - return sendto(sock, (const char*)data, len, 0, (sockaddr*)(dest ? &dest->addr : (raddr ? &raddr->addr : NULL)), sizeof(sockaddr_in)); - } - - int Socket::sendstr(const std::string& str, const Address* dest) { - return send((const uint8_t*)str.c_str(), str.length(), dest); - } - - int Socket::recv(uint8_t* data, size_t maxLen, bool forceLen, int timeout, Address* dest) { - // Create FD set - fd_set set; - FD_ZERO(&set); - FD_SET(sock, &set); - - // Define timeout - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = timeout * 1000; - - int read = 0; - bool blocking = (timeout != NONBLOCKING); - do { - // Wait for data or error if - if (blocking) { - int err = select(sock+1, &set, NULL, &set, (timeout > 0) ? &tv : NULL); - if (err <= 0) { return err; } - } - - // Receive - int addrLen = sizeof(sockaddr_in); - int err = ::recvfrom(sock, (char*)&data[read], maxLen - read, 0,(sockaddr*)(dest ? &dest->addr : NULL), (socklen_t*)(dest ? &addrLen : NULL)); - if (err <= 0 && !WOULD_BLOCK) { - close(); - return err; - } - read += err; - } - while (blocking && forceLen && read < maxLen); - return read; - } - - int Socket::recvline(std::string& str, int maxLen, int timeout, Address* dest) { - // Disallow nonblocking mode - if (!timeout) { return -1; } - - str.clear(); - int read = 0; - while (!maxLen || read < maxLen) { - char c; - int err = recv((uint8_t*)&c, 1, false, timeout, dest); - if (err <= 0) { return err; } - read++; - if (c == '\n') { break; } - str += c; - } - return read; - } - - // === Listener functions === - - Listener::Listener(SockHandle_t sock) { - this->sock = sock; - } - - Listener::~Listener() { - stop(); - } - - void Listener::stop() { - closeSocket(sock); - open = false; - } - - bool Listener::listening() { - return open; - } - - std::shared_ptr Listener::accept(Address* dest, int timeout) { - // Create FD set - fd_set set; - FD_ZERO(&set); - FD_SET(sock, &set); - - // Define timeout - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = timeout * 1000; - - // Wait for data or error - if (timeout != NONBLOCKING) { - int err = select(sock+1, &set, NULL, &set, (timeout > 0) ? &tv : NULL); - if (err <= 0) { return NULL; } - } - - // Accept - int addrLen = sizeof(sockaddr_in); - SockHandle_t s = ::accept(sock, (sockaddr*)(dest ? &dest->addr : NULL), (socklen_t*)(dest ? &addrLen : NULL)); - if ((int)s < 0) { - if (!WOULD_BLOCK) { stop(); } - return NULL; - } - - // Enable nonblocking mode - setNonblocking(s); - - return std::make_shared(s); - } - - // === Creation functions === - - std::map listInterfaces() { - // Init library if needed - init(); - - std::map ifaces; -#ifdef _WIN32 - // Pre-allocate buffer - ULONG size = sizeof(IP_ADAPTER_ADDRESSES); - PIP_ADAPTER_ADDRESSES addresses = (PIP_ADAPTER_ADDRESSES)malloc(size); - - // Reallocate to real size - if (GetAdaptersAddresses(AF_INET, 0, NULL, addresses, &size) == ERROR_BUFFER_OVERFLOW) { - addresses = (PIP_ADAPTER_ADDRESSES)realloc(addresses, size); - if (GetAdaptersAddresses(AF_INET, 0, NULL, addresses, &size)) { - throw std::exception("Could not list network interfaces"); - } - } - - // Save data - std::wstring_convert> utfConv; - for (auto iface = addresses; iface; iface = iface->Next) { - InterfaceInfo info; - auto ip = iface->FirstUnicastAddress; - if (!ip || ip->Address.lpSockaddr->sa_family != AF_INET) { continue; } - info.address = ntohl(*(uint32_t*)&ip->Address.lpSockaddr->sa_data[2]); - info.netmask = ~((1 << (32 - ip->OnLinkPrefixLength)) - 1); - info.broadcast = info.address | (~info.netmask); - ifaces[utfConv.to_bytes(iface->FriendlyName)] = info; - } - - // Free tables - free(addresses); -#else - // Get iface list - struct ifaddrs* addresses = NULL; - getifaddrs(&addresses); - - // Save data - for (auto iface = addresses; iface; iface = iface->ifa_next) { - if (iface->ifa_addr->sa_family != AF_INET) { continue; } - InterfaceInfo info; - info.address = ntohl(*(uint32_t*)&iface->ifa_addr->sa_data[2]); - info.netmask = ntohl(*(uint32_t*)&iface->ifa_netmask->sa_data[2]); - info.broadcast = info.address | (~info.netmask); - ifaces[iface->ifa_name] = info; - } - - // Free iface list - freeifaddrs(addresses); -#endif - - return ifaces; - } - - std::shared_ptr listen(const Address& addr) { - // Init library if needed - init(); - - // Create socket - SockHandle_t s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - // TODO: Support non-blockign mode - -#ifndef _WIN32 - // Allow port reusing if the app was killed or crashed - // and the socket is stuck in TIME_WAIT state. - // This option has a different meaning on Windows, - // so we use it only for non-Windows systems - int enable = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) { - closeSocket(s); - throw std::runtime_error("Could not configure socket"); - return NULL; - } -#endif - - // Bind socket to the port - if (bind(s, (sockaddr*)&addr.addr, sizeof(sockaddr_in))) { - closeSocket(s); - throw std::runtime_error("Could not bind socket"); - return NULL; - } - - // Enable listening - if (::listen(s, SOMAXCONN) != 0) { - throw std::runtime_error("Could start listening for connections"); - return NULL; - } - - // Enable nonblocking mode - setNonblocking(s); - - // Return listener class - return std::make_shared(s); - } - - std::shared_ptr listen(std::string host, int port) { - return listen(Address(host, port)); - } - - std::shared_ptr connect(const Address& addr) { - // Init library if needed - init(); - - // Create socket - SockHandle_t s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - // Connect to server - if (::connect(s, (sockaddr*)&addr.addr, sizeof(sockaddr_in))) { - closeSocket(s); - throw std::runtime_error("Could not connect"); - return NULL; - } - - // Enable nonblocking mode - setNonblocking(s); - - // Return socket class - return std::make_shared(s); - } - - std::shared_ptr connect(std::string host, int port) { - return connect(Address(host, port)); - } - - std::shared_ptr openudp(const Address& raddr, const Address& laddr) { - // Init library if needed - init(); - - // Create socket - SockHandle_t s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - - // Bind socket to local port - if (bind(s, (sockaddr*)&laddr.addr, sizeof(sockaddr_in))) { - closeSocket(s); - throw std::runtime_error("Could not bind socket"); - return NULL; - } - - // Return socket class - return std::make_shared(s, &raddr); - } - - std::shared_ptr openudp(std::string rhost, int rport, const Address& laddr) { - return openudp(Address(rhost, rport), laddr); - } - - std::shared_ptr openudp(const Address& raddr, std::string lhost, int lport) { - return openudp(raddr, Address(lhost, lport)); - } - - std::shared_ptr openudp(std::string rhost, int rport, std::string lhost, int lport) { - return openudp(Address(rhost, rport), Address(lhost, lport)); - } -} \ No newline at end of file diff --git a/source_modules/spectran_http_source/src/net.h b/source_modules/spectran_http_source/src/net.h deleted file mode 100644 index a35a6fbb..00000000 --- a/source_modules/spectran_http_source/src/net.h +++ /dev/null @@ -1,281 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -namespace net { -#ifdef _WIN32 - typedef SOCKET SockHandle_t; - typedef int socklen_t; -#else - typedef int SockHandle_t; -#endif - typedef uint32_t IP_t; - - class Socket; - class Listener; - - struct InterfaceInfo { - IP_t address; - IP_t netmask; - IP_t broadcast; - }; - - class Address { - friend Socket; - friend Listener; - public: - /** - * Default constructor. Corresponds to 0.0.0.0:0. - */ - Address(); - - /** - * Do not instantiate this class manually. Use the provided functions. - * @param host Hostname or IP. - * @param port TCP/UDP port. - */ - Address(const std::string& host, int port); - - /** - * Do not instantiate this class manually. Use the provided functions. - * @param ip IP in host byte order. - * @param port TCP/UDP port. - */ - Address(IP_t ip, int port); - - /** - * Get the IP address. - * @return IP address in standard string format. - */ - std::string getIPStr(); - - /** - * Get the IP address. - * @return IP address in host byte order. - */ - IP_t getIP(); - - /** - * Set the IP address. - * @param ip IP address in host byte order. - */ - void setIP(IP_t ip); - - /** - * Get the TCP/UDP port. - * @return TCP/UDP port number. - */ - int getPort(); - - /** - * Set the TCP/UDP port. - * @param port TCP/UDP port number. - */ - void setPort(int port); - - struct sockaddr_in addr; - }; - - enum { - NO_TIMEOUT = -1, - NONBLOCKING = 0 - }; - - enum SocketType { - SOCKET_TYPE_TCP, - SOCKET_TYPE_UDP - }; - - class Socket { - public: - /** - * Do not instantiate this class manually. Use the provided functions. - */ - Socket(SockHandle_t sock, const Address* raddr = NULL); - ~Socket(); - - /** - * Close socket. The socket can no longer be used after this. - */ - void close(); - - /** - * Check if the socket is open. - * @return True if open, false if closed. - */ - bool isOpen(); - - /** - * Get socket type. Either TCP or UDP. - * @return Socket type. - */ - SocketType type(); - - /** - * Send data on socket. - * @param data Data to be sent. - * @param len Number of bytes to be sent. - * @param dest Destination address. NULL to use the default remote address. - * @return Number of bytes sent. - */ - int send(const uint8_t* data, size_t len, const Address* dest = NULL); - - /** - * Send string on socket. Terminating NULL byte is not sent, include one in the string if you need it. - * @param str String to be sent. - * @param dest Destination address. NULL to use the default remote address. - * @return Number of bytes sent. - */ - int sendstr(const std::string& str, const Address* dest = NULL); - - /** - * Receive data from socket. - * @param data Buffer to read the data into. - * @param maxLen Maximum number of bytes to read. - * @param forceLen Read the maximum number of bytes even if it requires multiple receive operations. - * @param timeout Timeout in milliseconds. Use NO_TIMEOUT or NONBLOCKING here if needed. - * @param dest Destination address. If multiple packets, this will contain the address of the last one. NULL if not used. - * @return Number of bytes read. 0 means timed out or closed. -1 means would block or error. - */ - int recv(uint8_t* data, size_t maxLen, bool forceLen = false, int timeout = NO_TIMEOUT, Address* dest = NULL); - - /** - * Receive line from socket. - * @param str String to read the data into. - * @param maxLen Maximum line length allowed, 0 for no limit. - * @param timeout Timeout in milliseconds. Use NO_TIMEOUT or NONBLOCKING here if needed. - * @param dest Destination address. If multiple packets, this will contain the address of the last one. NULL if not used. - * @return Length of the returned string. 0 means timed out or closed. -1 means would block or error. - */ - int recvline(std::string& str, int maxLen = 0, int timeout = NO_TIMEOUT, Address* dest = NULL); - - private: - Address* raddr = NULL; - SockHandle_t sock; - bool open = true; - - }; - - class Listener { - public: - /** - * Do not instantiate this class manually. Use the provided functions. - */ - Listener(SockHandle_t sock); - ~Listener(); - - /** - * Stop listening. The listener can no longer be used after this. - */ - void stop(); - - /** - * CHeck if the listener is still listening. - * @return True if listening, false if not. - */ - bool listening(); - - /** - * Accept connection. - * @param timeout Timeout in milliseconds. Use NO_TIMEOUT or NONBLOCKING here if needed. - * @return Socket of the connection. NULL means timed out, would block or closed. - */ - std::shared_ptr accept(Address* dest = NULL, int timeout = NO_TIMEOUT); - - private: - SockHandle_t sock; - bool open = true; - - }; - - /** - * Get a list of the network interface. - * @return List of network interfaces and their addresses. - */ - std::map listInterfaces(); - - /** - * Create TCP listener. - * @param addr Address to listen on. - * @return Listener instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr listen(const Address& addr); - - /** - * Create TCP listener. - * @param host Hostname or IP to listen on ("0.0.0.0" for Any). - * @param port Port to listen on. - * @return Listener instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr listen(std::string host, int port); - - /** - * Create TCP connection. - * @param addr Remote address. - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr connect(const Address& addr); - - /** - * Create TCP connection. - * @param host Remote hostname or IP address. - * @param port Remote port. - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr connect(std::string host, int port); - - /** - * Create UDP socket. - * @param raddr Remote address. - * @param laddr Local address to bind the socket to. - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr openudp(const Address& raddr, const Address& laddr); - - /** - * Create UDP socket. - * @param rhost Remote hostname or IP address. - * @param rport Remote port. - * @param laddr Local address to bind the socket to. - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr openudp(std::string rhost, int rport, const Address& laddr); - - /** - * Create UDP socket. - * @param raddr Remote address. - * @param lhost Local hostname or IP used to bind the socket (optional, "0.0.0.0" for Any). - * @param lpost Local port used to bind the socket to (optional, 0 to allocate automatically). - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr openudp(const Address& raddr, std::string lhost = "0.0.0.0", int lport = 0); - - /** - * Create UDP socket. - * @param rhost Remote hostname or IP address. - * @param rport Remote port. - * @param lhost Local hostname or IP used to bind the socket (optional, "0.0.0.0" for Any). - * @param lpost Local port used to bind the socket to (optional, 0 to allocate automatically). - * @return Socket instance on success, Throws runtime_error otherwise. - */ - std::shared_ptr openudp(std::string rhost, int rport, std::string lhost = "0.0.0.0", int lport = 0); -} \ No newline at end of file diff --git a/source_modules/spectran_http_source/src/proto/http.cpp b/source_modules/spectran_http_source/src/proto/http.cpp deleted file mode 100644 index 8821f976..00000000 --- a/source_modules/spectran_http_source/src/proto/http.cpp +++ /dev/null @@ -1,304 +0,0 @@ -#include "http.h" -#include - -namespace net::http { - std::string MessageHeader::serialize() { - std::string data; - - // Add start line - data += serializeStartLine() + "\r\n"; - - // Add fields - for (const auto& [key, value] : fields) { - data += key + ": " + value + "\r\n"; - } - - // Add terminator - data += "\r\n"; - - return data; - } - - void MessageHeader::deserialize(const std::string& data) { - // Clear existing fields - fields.clear(); - - // Parse first line - std::string line; - int offset = readLine(data, line); - deserializeStartLine(line); - - // Parse fields - while (offset < data.size()) { - // Read line - offset = readLine(data, line, offset); - - // If empty line, the header is done - if (line.empty()) { break; } - - // Read until first ':' for the key - int klen = 0; - for (; klen < line.size(); klen++) { - if (line[klen] == ':') { break; } - } - - // Find offset of value - int voff = klen + 1; - for (; voff < line.size(); voff++) { - if (line[voff] != ' ' && line[voff] != '\t') { break; } - } - - // Save field - fields[line.substr(0, klen)] = line.substr(voff); - } - } - - std::map& MessageHeader::getFields() { - return fields; - } - - bool MessageHeader::hasField(const std::string& name) { - return fields.find(name) != fields.end(); - } - - std::string MessageHeader::getField(const std::string name) { - // TODO: Check if exists - return fields[name]; - } - - void MessageHeader::setField(const std::string& name, const std::string& value) { - fields[name] = value; - } - - void MessageHeader::clearField(const std::string& name) { - // TODO: Check if exists (but maybe no error?) - fields.erase(name); - } - - int MessageHeader::readLine(const std::string& str, std::string& line, int start) { - // Get line length - int len = 0; - bool cr = false; - for (int i = start; i < str.size(); i++) { - if (str[i] == '\n') { - if (len && str[i-1] == '\r') { cr = true; } - break; - } - len++; - } - - // Copy line - line = str.substr(start, len - (cr ? 1:0)); - return start + len + 1; - } - - RequestHeader::RequestHeader(Method method, std::string uri, std::string host) { - this->method = method; - this->uri = uri; - setField("Host", host); - } - - RequestHeader::RequestHeader(const std::string& data) { - deserialize(data); - } - - Method RequestHeader::getMethod() { - return method; - } - - void RequestHeader::setMethod(Method method) { - this->method = method; - } - - std::string RequestHeader::getURI() { - return uri; - } - - void RequestHeader::setURI(const std::string& uri) { - this->uri = uri; - } - - void RequestHeader::deserializeStartLine(const std::string& data) { - // TODO - } - - std::string RequestHeader::serializeStartLine() { - // TODO: Allow to specify version - return MethodStrings[method] + " " + uri + " HTTP/1.1"; - } - - ResponseHeader::ResponseHeader(StatusCode statusCode) { - this->statusCode = statusCode; - if (StatusCodeStrings.find(statusCode) != StatusCodeStrings.end()) { - this->statusString = StatusCodeStrings[statusCode]; - } - else { - this->statusString = "UNKNOWN"; - } - } - - ResponseHeader::ResponseHeader(StatusCode statusCode, const std::string& statusString) { - this->statusCode = statusCode; - this->statusString = statusString; - } - - ResponseHeader::ResponseHeader(const std::string& data) { - deserialize(data); - } - - StatusCode ResponseHeader::getStatusCode() { - return statusCode; - } - - void ResponseHeader::setStatusCode(StatusCode statusCode) { - this->statusCode = statusCode; - } - - std::string ResponseHeader::getStatusString() { - return statusString; - } - - void ResponseHeader::setStatusString(const std::string& statusString) { - this->statusString = statusString; - } - - void ResponseHeader::deserializeStartLine(const std::string& data) { - // Parse version - int offset = 0; - for (; offset < data.size(); offset++) { - if (data[offset] == ' ') { break; } - } - // TODO: Error if null length - // TODO: Parse version - - // Skip spaces - for (; offset < data.size(); offset++) { - if (data[offset] != ' ' && data[offset] != '\t') { break; } - } - - // Parse status code - int codeOffset = offset; - for (; offset < data.size(); offset++) { - if (data[offset] == ' ') { break; } - } - // TODO: Error if null length - statusCode = (StatusCode)std::stoi(data.substr(codeOffset, codeOffset - offset)); - - // Skip spaces - for (; offset < data.size(); offset++) { - if (data[offset] != ' ' && data[offset] != '\t') { break; } - } - - // Parse status string - int stringOffset = offset; - for (; offset < data.size(); offset++) { - if (data[offset] == ' ') { break; } - } - // TODO: Error if null length (maybe?) - statusString = data.substr(stringOffset, stringOffset - offset); - } - - std::string ResponseHeader::serializeStartLine() { - char buf[1024]; - sprintf(buf, "%d %s", (int)statusCode, statusString.c_str()); - return buf; - } - - ChunkHeader::ChunkHeader(size_t length) { - this->length = length; - } - - ChunkHeader::ChunkHeader(const std::string& data) { - deserialize(data); - } - - std::string ChunkHeader::serialize() { - char buf[64]; - sprintf(buf, "%" PRIX64 "\r\n", length); - return buf; - } - - void ChunkHeader::deserialize(const std::string& data) { - // Parse length - int offset = 0; - for (; offset < data.size(); offset++) { - if (data[offset] == ' ') { break; } - } - // TODO: Error if null length - length = (StatusCode)std::stoull(data.substr(0, offset), nullptr, 16); - - // TODO: Parse rest - } - - size_t ChunkHeader::getLength() { - return length; - } - - void ChunkHeader::setLength(size_t length) { - this->length = length; - } - - Client::Client(std::shared_ptr sock) { - this->sock = sock; - } - - int Client::sendRequestHeader(RequestHeader& req) { - return sock->sendstr(req.serialize()); - } - - int Client::recvRequestHeader(RequestHeader& req, int timeout) { - // Non-blocking mode not alloowed - if (!timeout) { return -1; } - - // Read response - std::string respData; - int err = recvHeader(respData, timeout); - if (err) { return err; } - - // Deserialize - req.deserialize(respData); - } - - int Client::sendResponseHeader(ResponseHeader& resp) { - return sock->sendstr(resp.serialize()); - } - - int Client::recvResponseHeader(ResponseHeader& resp, int timeout) { - // Non-blocking mode not alloowed - if (!timeout) { return -1; } - - // Read response - std::string respData; - int err = recvHeader(respData, timeout); - if (err) { return err; } - - // Deserialize - resp.deserialize(respData); - } - - int Client::sendChunkHeader(ChunkHeader& chdr) { - return sock->sendstr(chdr.serialize()); - } - - int Client::recvChunkHeader(ChunkHeader& chdr, int timeout) { - std::string respData; - int err = sock->recvline(respData, 0, timeout); - if (err <= 0) { return err; } - if (respData[respData.size()-1] == '\r') { - respData.pop_back(); - } - chdr.deserialize(respData); - return 0; - } - - int Client::recvHeader(std::string& data, int timeout) { - while (sock->isOpen()) { - std::string line; - int ret = sock->recvline(line); - if (line == "\r") { break; } - if (ret <= 0) { return ret; } - data += line + "\n"; - } - return 0; - } -} \ No newline at end of file diff --git a/source_modules/spectran_http_source/src/proto/http.h b/source_modules/spectran_http_source/src/proto/http.h deleted file mode 100644 index 77901ec7..00000000 --- a/source_modules/spectran_http_source/src/proto/http.h +++ /dev/null @@ -1,276 +0,0 @@ -#pragma once -#include -#include -#include "../net.h" - -namespace net::http { - enum Method { - METHOD_OPTIONS, - METHOD_GET, - METHOD_HEAD, - METHOD_POST, - METHOD_PUT, - METHOD_DELETE, - METHOD_TRACE, - METHOD_CONNECT - }; - - inline std::map MethodStrings { - { METHOD_OPTIONS, "OPTIONS" }, - { METHOD_GET, "GET" }, - { METHOD_HEAD, "HEAD" }, - { METHOD_POST, "POST" }, - { METHOD_PUT, "PUT" }, - { METHOD_DELETE, "DELETE" }, - { METHOD_TRACE, "TRACE" }, - { METHOD_CONNECT, "CONNECT" } - }; - - enum StatusCode { - STATUS_CODE_CONTINUE = 100, - STATUS_CODE_SWITCH_PROTO = 101, - - STATUS_CODE_OK = 200, - STATUS_CODE_CREATED = 201, - STATUS_CODE_ACCEPTED = 202, - STATUS_CODE_NON_AUTH_INFO = 203, - STATUS_CODE_NO_CONTENT = 204, - STATUS_CODE_RESET_CONTENT = 205, - STATUS_CODE_PARTIAL_CONTENT = 206, - - STATUS_CODE_MULTIPLE_CHOICES = 300, - STATUS_CODE_MOVED_PERMANENTLY = 301, - STATUS_CODE_FOUND = 302, - STATUS_CODE_SEE_OTHER = 303, - STATUS_CODE_NOT_MODIFIED = 304, - STATUS_CODE_USE_PROXY = 305, - STATUS_CODE_TEMP_REDIRECT = 307, - - STATUS_CODE_BAD_REQUEST = 400, - STATUS_CODE_UNAUTHORIZED = 401, - STATUS_CODE_PAYMENT_REQUIRED = 402, - STATUS_CODE_FORBIDDEN = 403, - STATUS_CODE_NOT_FOUND = 404, - STATUS_CODE_METHOD_NOT_ALLOWED = 405, - STATUS_CODE_NOT_ACCEPTABLE = 406, - STATUS_CODE_PROXY_AUTH_REQ = 407, - STATUS_CODE_REQUEST_TIEMOUT = 408, - STATUS_CODE_CONFLICT = 409, - STATUS_CODE_GONE = 410, - STATUS_CODE_LENGTH_REQUIRED = 411, - STATUS_CODE_PRECONDITION_FAILED = 412, - STATUS_CODE_REQ_ENTITY_TOO_LARGE = 413, - STATUS_CODE_REQ_URI_TOO_LONG = 414, - STATUS_CODE_UNSUPPORTED_MEDIA_TYPE = 415, - STATUS_CODE_REQ_RANGE_NOT_SATISFIABLE = 416, - STATUS_CODE_EXPECTATION_FAILED = 417, - STATUS_CODE_IM_A_TEAPOT = 418, - STATUS_CODE_ENHANCE_YOUR_CALM = 420, - - STATUS_CODE_INTERNAL_SERVER_ERROR = 500, - STATUS_CODE_NOT_IMPLEMENTED = 501, - STATUS_CODE_BAD_GATEWAY = 502, - STATUS_CODE_SERVICE_UNAVAILABLE = 503, - STATUS_CODE_GATEWAY_TIMEOUT = 504, - STATUS_CODE_HTTP_VERSION_UNSUPPORTED = 505 - }; - - inline std::map StatusCodeStrings { - { STATUS_CODE_CONTINUE , "CONTINUE" }, - { STATUS_CODE_SWITCH_PROTO , "SWITCH_PROTO" }, - - { STATUS_CODE_OK , "OK" }, - { STATUS_CODE_CREATED , "CREATED" }, - { STATUS_CODE_ACCEPTED , "ACCEPTED" }, - { STATUS_CODE_NON_AUTH_INFO , "NON_AUTH_INFO" }, - { STATUS_CODE_NO_CONTENT , "NO_CONTENT" }, - { STATUS_CODE_RESET_CONTENT , "RESET_CONTENT" }, - { STATUS_CODE_PARTIAL_CONTENT , "PARTIAL_CONTENT" }, - - { STATUS_CODE_MULTIPLE_CHOICES , "MULTIPLE_CHOICES" }, - { STATUS_CODE_MOVED_PERMANENTLY , "MOVED_PERMANENTLY" }, - { STATUS_CODE_FOUND , "FOUND" }, - { STATUS_CODE_SEE_OTHER , "SEE_OTHER" }, - { STATUS_CODE_NOT_MODIFIED , "NOT_MODIFIED" }, - { STATUS_CODE_USE_PROXY , "USE_PROXY" }, - { STATUS_CODE_TEMP_REDIRECT , "TEMP_REDIRECT" }, - - { STATUS_CODE_BAD_REQUEST , "BAD_REQUEST" }, - { STATUS_CODE_UNAUTHORIZED , "UNAUTHORIZED" }, - { STATUS_CODE_PAYMENT_REQUIRED , "PAYMENT_REQUIRED" }, - { STATUS_CODE_FORBIDDEN , "FORBIDDEN" }, - { STATUS_CODE_NOT_FOUND , "NOT_FOUND" }, - { STATUS_CODE_METHOD_NOT_ALLOWED , "METHOD_NOT_ALLOWED" }, - { STATUS_CODE_NOT_ACCEPTABLE , "NOT_ACCEPTABLE" }, - { STATUS_CODE_PROXY_AUTH_REQ , "PROXY_AUTH_REQ" }, - { STATUS_CODE_REQUEST_TIEMOUT , "REQUEST_TIEMOUT" }, - { STATUS_CODE_CONFLICT , "CONFLICT" }, - { STATUS_CODE_GONE , "GONE" }, - { STATUS_CODE_LENGTH_REQUIRED , "LENGTH_REQUIRED" }, - { STATUS_CODE_PRECONDITION_FAILED , "PRECONDITION_FAILED" }, - { STATUS_CODE_REQ_ENTITY_TOO_LARGE , "REQ_ENTITY_TOO_LARGE" }, - { STATUS_CODE_REQ_URI_TOO_LONG , "REQ_URI_TOO_LONG" }, - { STATUS_CODE_UNSUPPORTED_MEDIA_TYPE , "UNSUPPORTED_MEDIA_TYPE" }, - { STATUS_CODE_REQ_RANGE_NOT_SATISFIABLE, "REQ_RANGE_NOT_SATISFIABLE"}, - { STATUS_CODE_EXPECTATION_FAILED , "EXPECTATION_FAILED" }, - { STATUS_CODE_IM_A_TEAPOT , "IM_A_TEAPOT" }, - { STATUS_CODE_ENHANCE_YOUR_CALM , "ENHANCE_YOUR_CALM" }, - - { STATUS_CODE_INTERNAL_SERVER_ERROR , "INTERNAL_SERVER_ERROR" }, - { STATUS_CODE_NOT_IMPLEMENTED , "NOT_IMPLEMENTED" }, - { STATUS_CODE_BAD_GATEWAY , "BAD_GATEWAY" }, - { STATUS_CODE_SERVICE_UNAVAILABLE , "SERVICE_UNAVAILABLE" }, - { STATUS_CODE_GATEWAY_TIMEOUT , "GATEWAY_TIMEOUT" }, - { STATUS_CODE_HTTP_VERSION_UNSUPPORTED , "HTTP_VERSION_UNSUPPORTED" } - }; - - /** - * HTTP Message Header - */ - class MessageHeader { - public: - /** - * Serialize header to string. - * @return Header in string form. - */ - std::string serialize(); - - /** - * Deserialize header from string. - * @param data Header in string form. - */ - void deserialize(const std::string& data); - - /** - * Get field list. - * @return Map from field name to field. - */ - std::map& getFields(); - - /** - * Check if a field exists in the header. - * @return True if the field exists, false otherwise. - */ - bool hasField(const std::string& name); - - /** - * Get field value. - * @param name Name of the field. - * @return Field value. - */ - std::string getField(const std::string name); - - /** - * Set field. - * @param name Field name. - * @param value Field value. - */ - void setField(const std::string& name, const std::string& value); - - /** - * Delete field. - * @param name Field name. - */ - void clearField(const std::string& name); - - private: - int readLine(const std::string& str, std::string& line, int start = 0); - virtual std::string serializeStartLine() = 0; - virtual void deserializeStartLine(const std::string& data) = 0; - std::map fields; - }; - - /** - * HTTP Request Header - */ - class RequestHeader : public MessageHeader { - public: - RequestHeader() {} - - /** - * Create request header from the mandatory parameters. - * @param method HTTP Method. - * @param uri URI of request. - * @param host Server host passed in the 'Host' field. - */ - RequestHeader(Method method, std::string uri, std::string host); - - /** - * Create request header from its serialized string form. - * @param data Request header in string form. - */ - RequestHeader(const std::string& data); - - /** - * Get HTTP Method. - * @return HTTP Method. - */ - Method getMethod(); - void setMethod(Method method); - std::string getURI(); - void setURI(const std::string& uri); - - private: - void deserializeStartLine(const std::string& data); - std::string serializeStartLine(); - - Method method; - std::string uri; - }; - - class ResponseHeader : public MessageHeader { - public: - ResponseHeader() {} - ResponseHeader(StatusCode statusCode); - ResponseHeader(StatusCode statusCode, const std::string& statusString); - ResponseHeader(const std::string& data); - - StatusCode getStatusCode(); - void setStatusCode(StatusCode statusCode); - std::string getStatusString(); - void setStatusString(const std::string& statusString); - - private: - void deserializeStartLine(const std::string& data); - std::string serializeStartLine(); - - StatusCode statusCode; - std::string statusString; - }; - - class ChunkHeader { - public: - ChunkHeader() {} - ChunkHeader(size_t length); - ChunkHeader(const std::string& data); - - std::string serialize(); - void deserialize(const std::string& data); - - size_t getLength(); - void setLength(size_t length); - - private: - size_t length; - }; - - class Client { - public: - Client() {} - Client(std::shared_ptr sock); - - int sendRequestHeader(RequestHeader& req); - int recvRequestHeader(RequestHeader& req, int timeout = -1); - int sendResponseHeader(ResponseHeader& resp); - int recvResponseHeader(ResponseHeader& resp, int timeout = -1); - int sendChunkHeader(ChunkHeader& chdr); - int recvChunkHeader(ChunkHeader& chdr, int timeout = -1); - - private: - int recvHeader(std::string& data, int timeout = -1); - std::shared_ptr sock; - - }; - - -} \ No newline at end of file diff --git a/source_modules/spectran_http_source/src/spectran_http_client.h b/source_modules/spectran_http_source/src/spectran_http_client.h index eef15579..96e5cbae 100644 --- a/source_modules/spectran_http_source/src/spectran_http_client.h +++ b/source_modules/spectran_http_source/src/spectran_http_client.h @@ -3,7 +3,7 @@ #include #include #include -#include "proto/http.h" +#include class SpectranHTTPClient { public: diff --git a/source_modules/spectran_source/src/main.cpp b/source_modules/spectran_source/src/main.cpp index 4bc99eef..faac3790 100644 --- a/source_modules/spectran_source/src/main.cpp +++ b/source_modules/spectran_source/src/main.cpp @@ -279,9 +279,9 @@ private: AARTSAAPI_Packet pkt = { sizeof(AARTSAAPI_Packet) }; while (AARTSAAPI_GetPacket(&_this->dev, 0, 0, &pkt) == AARTSAAPI_EMPTY) { #ifdef _WIN32 - Sleep(1); + Sleep(1); #else - usleep(1000); + usleep(1000); #endif } @@ -371,7 +371,7 @@ private: if (_this->agcModeId) { SmGui::BeginDisabled(); } SmGui::LeftLabel("Ref Level"); SmGui::FillWidth(); - if (SmGui::SliderFloatWithSteps(CONCAT("##_spectran_ref_", _this->name), &_this->refLevel, -20.0f, 10.0f, 0.5f, SmGui::FMT_STR_FLOAT_DB_ONE_DECIMAL)) { + if (SmGui::SliderFloatWithSteps(CONCAT("##_spectran_ref_", _this->name), &_this->refLevel, _this->minRef, _this->maxRef, _this->refStep, SmGui::FMT_STR_FLOAT_DB_ONE_DECIMAL)) { if (_this->running) { AARTSAAPI_Config config; AARTSAAPI_ConfigFind(&_this->dev, &_this->croot, &config, L"main/reflevel"); @@ -442,6 +442,22 @@ private: else { AARTSAAPI_ConfigSetString(&dev, &config, L"None"); } + updateRef(); + } + + void updateRef() { + // Get and update bounds + AARTSAAPI_Config config; + AARTSAAPI_ConfigInfo refInfo; + AARTSAAPI_ConfigFind(&dev, &croot, &config, L"main/reflevel"); + AARTSAAPI_ConfigGetInfo(&dev, &config, &refInfo); + minRef = refInfo.minValue; + maxRef = refInfo.maxValue; + refStep = refInfo.stepValue; + refLevel = std::clamp(refLevel, minRef, maxRef); + + // Apply new ref level + AARTSAAPI_ConfigSetFloat(&dev, &config, refLevel); } const double clockRates[4] = { @@ -482,6 +498,9 @@ private: float refLevel = -20.0f; bool amp = false; bool preAmp = false; + float minRef = -20.0f; + float maxRef = 10.0f; + float refStep = 0.5; struct SRCombo { bool operator==(const SRCombo& b) { diff --git a/source_modules/usrp_source/src/main.cpp b/source_modules/usrp_source/src/main.cpp index 793d4887..0971a86c 100644 --- a/source_modules/usrp_source/src/main.cpp +++ b/source_modules/usrp_source/src/main.cpp @@ -136,7 +136,7 @@ public: // List samplerates samplerates.clear(); auto srList = dev->get_rx_rates(chanId); - for (auto& l : srList) { + for (const auto& l : srList) { double step = (l.step() == 0.0) ? 100e3 : l.step(); for (double f = l.start(); f <= l.stop(); f += step) { samplerates.define(f, getBandwdithScaled(f), f); @@ -173,7 +173,7 @@ public: clockSources.define(s, name, s); spdlog::warn(s); } - + // Load settings srId = 0; antId = 0;