Added more net functions and a generic TCPServer

This commit is contained in:
Maschell 2018-03-07 18:42:04 +01:00
parent 169468ad60
commit d3657d14eb
5 changed files with 276 additions and 16 deletions

View File

@ -109,6 +109,7 @@ install:
@mkdir -p $(INCLUDEDIR)/language/
@mkdir -p $(INCLUDEDIR)/fs/
@cp source/utils/*.h $(INCLUDEDIR)/utils/
@cp source/utils/*.hpp $(INCLUDEDIR)/utils/
@cp source/system/*.h $(INCLUDEDIR)/system/
@cp source/language/*.h $(INCLUDEDIR)/language/
@cp source/fs/*.h $(INCLUDEDIR)/fs/

130
source/utils/TCPServer.cpp Normal file
View File

@ -0,0 +1,130 @@
#include "TCPServer.hpp"
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <dynamic_libs/nn_act_functions.h>
#include "logger.h"
#include "net.h"
#define wiiu_errno (*__gh_errno_ptr())
TCPServer::TCPServer(s32 port,s32 priority) {
this->port = port;
this->sockfd = -1;
this->clientfd = -1;
memset(&(this->sock_addr),0,sizeof(this->sock_addr));
pThread = CThread::create(TCPServer::DoTCPThread, (void*)this, CThread::eAttributeAffCore2,priority);
pThread->resumeThread();
}
TCPServer::~TCPServer() {
CloseSockets();
DEBUG_FUNCTION_LINE("Thread will be closed\n");
exitThread = 1;
ICInvalidateRange((void*)&exitThread, 4);
DCFlushRange((void*)&exitThread, 4);
if(pThread != NULL) {
DEBUG_FUNCTION_LINE("Deleting it!\n");
delete pThread;
}
DEBUG_FUNCTION_LINE("Thread done\n");
pThread = NULL;
}
void TCPServer::CloseSockets() {
if (this->sockfd != -1) {
socketclose(this->sockfd);
}
if (this->clientfd != -1) {
socketclose(this->clientfd);
}
this->sockfd = -1;
this->clientfd = -1;
}
void TCPServer::ErrorHandling() {
CloseSockets();
os_usleep(1000*1000*2);
}
void TCPServer::DoTCPThreadInternal() {
s32 ret;
s32 len;
connected = false;
while (1) {
if(exitThread) {
break;
}
memset(&(this->sock_addr),0,sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = this->port;
sock_addr.sin_addr.s_addr = 0;
this->sockfd = ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ret == -1) {
ErrorHandling();
continue;
}
s32 enable = 1;
setsockopt(this->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
ret = bind(this->sockfd, (sockaddr *)&sock_addr, 16);
if(ret < 0) {
ErrorHandling();
continue;
}
ret = listen(this->sockfd, 1);
if(ret < 0) {
ErrorHandling();
continue;
}
do {
DEBUG_FUNCTION_LINE("Waiting for a connection\n");
if(exitThread) {
break;
}
len = 16;
clientfd = ret = accept(sockfd, (sockaddr *)&(sock_addr), &len);
if(ret == -1) {
ErrorHandling();
break;
}
if(!acceptConnection()) {
ErrorHandling();
break;
}
connected = true;
DEBUG_FUNCTION_LINE("Connection accepted\n");
whileLoop();
DEBUG_FUNCTION_LINE("Client disconnected\n");
if(clientfd != -1) {
socketclose(clientfd);
}
clientfd = -1;
} while(0);
DEBUG_FUNCTION_LINE("Closing TCPServer\n");
connected = false;
onConnectionClosed();
CloseSockets();
continue;
}
DEBUG_FUNCTION_LINE("Ending DoTCPThreadInternal\n");
}
void TCPServer::DoTCPThread(CThread *thread, void *arg) {
TCPServer * args = (TCPServer * )arg;
return args->DoTCPThreadInternal();
}

View File

@ -0,0 +1,61 @@
#ifndef _TCPSERVER_H_
#define _TCPSERVER_H_
#include <dynamic_libs/socket_functions.h>
#include <dynamic_libs/os_functions.h>
#include <system/CThread.h>
class TCPServer {
public:
TCPServer(s32 port, s32 priority);
virtual ~TCPServer();
bool isConnected() {
return connected;
}
protected:
bool shouldExit() {
return (exitThread == 1);
}
s32 getClientFD() {
return clientfd;
}
s32 getSocketFD() {
return sockfd;
}
struct sockaddr_in getSockAddr() {
return sock_addr;
}
private:
virtual void CloseSockets();
virtual void ErrorHandling();
static void DoTCPThread(CThread *thread, void *arg);
virtual void DoTCPThreadInternal();
virtual bool acceptConnection() = 0;
virtual void onConnectionClosed(){
DEBUG_FUNCTION_LINE("Default onConnectionClosed \n");
}
/**
Called when a connection has be accepted.
**/
virtual bool whileLoop() = 0;
struct sockaddr_in sock_addr;
volatile s32 sockfd = -1;
volatile s32 clientfd = -1;
s32 port = 0;
volatile bool connected = false;
volatile s32 exitThread = 0;
CThread *pThread = NULL;
};
#endif //_TCPSERVER_H_

View File

@ -1,20 +1,81 @@
#include "dynamic_libs/socket_functions.h"
#include "net.h"
#include <dynamic_libs/os_functions.h>
#include <dynamic_libs/socket_functions.h>
int recvwait(int sock, unsigned char *buffer, int len)
{
int recvBytes = 0;
static volatile int socket_lock __attribute__((section(".data"))) = 0;
while(len)
{
int ret = recv(sock, buffer, len, 0);
if(ret <= 0) {
s32 recvwait(s32 sock, void *buffer, s32 len) {
while(socket_lock) {
os_usleep(1000);
}
s32 ret;
while (len > 0) {
ret = recv(sock, buffer, len, 0);
if(ret < 0) {
socket_lock = 0;
return ret;
}
len -= ret;
buffer += ret;
recvBytes += ret;
buffer = (void *)(((char *) buffer) + ret);
}
return recvBytes;
socket_lock = 0;
return 0;
}
u8 recvbyte(s32 sock) {
unsigned char buffer[1];
s32 ret;
ret = recvwait(sock, buffer, 1);
if (ret < 0) return ret;
return buffer[0];
}
u32 recvword(s32 sock) {
u32 result;
s32 ret;
ret = recvwait(sock, &result, 4);
if (ret < 0) return ret;
return result;
}
s32 checkbyte(s32 sock) {
while(socket_lock) {
os_usleep(1000);
}
unsigned char buffer[1];
s32 ret;
ret = recv(sock, buffer, 1, MSG_DONTWAIT);
socket_lock = 0;
if (ret < 0) return ret;
if (ret == 0) return -1;
return buffer[0];
}
s32 sendwait(s32 sock, const void *buffer, s32 len) {
while(socket_lock) {
os_usleep(1000);
}
s32 ret;
while (len > 0) {
// For some reason the send blocks/crashes if the buffer is too big..
int cur_length = len <= 0x30 ? len : 0x30;
ret = send(sock, buffer, cur_length, 0);
if(ret < 0) {
socket_lock = 0;
return ret;
}
len -= ret;
buffer = (void *)(((char *) buffer) + ret);
}
socket_lock = 0;
return 0;
}
s32 sendbyte(s32 sock, unsigned char byte) {
unsigned char buffer[1];
buffer[0] = byte;
return sendwait(sock, buffer, 1);
}

View File

@ -1,11 +1,18 @@
#ifndef __NET_H_
#define __NET_H_
#ifndef _UTILS_NET_H_
#define _UTILS_NET_H_
#include <dynamic_libs/os_types.h>
#ifdef __cplusplus
extern "C" {
#endif
int recvwait(int sock, unsigned char *buffer, int len);
s32 recvwait(s32 sock, void *buffer, s32 len);
u8 recvbyte(s32 sock);
u32 recvword(s32 sock);
s32 checkbyte(s32 sock);
s32 sendwait(s32 sock, const void *buffer, s32 len);
s32 sendbyte(s32 sock, unsigned char byte);
#ifdef __cplusplus
}