frontlib/ipcconn.c
author Medo <smaxein@googlemail.com>
Thu, 31 May 2012 18:32:01 +0200
changeset 7158 a0573014ff4f
permissions -rw-r--r--
Further work on the frontend library, restructuring, ...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7158
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     1
#include "ipcconn.h"
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     2
#include "logging.h"
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     3
#include "nonblocksockets.h"
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     4
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     5
#include <SDL_net.h>
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     6
#include <time.h>
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     7
static TCPsocket ipcListenSocket;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     8
static NonBlockSocket ipcConnSocket;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
     9
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    10
static uint8_t ipcReadBuffer[256];
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    11
static int ipcReadBufferSize;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    12
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    13
void flib_ipcconn_init() {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    14
	ipcListenSocket = NULL;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    15
	ipcConnSocket = NULL;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    16
	ipcReadBufferSize = 0;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    17
}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    18
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    19
void flib_ipcconn_quit() {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    20
	flib_ipcconn_close();
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    21
}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    22
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    23
int flib_ipcconn_listen() {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    24
	if(ipcListenSocket || ipcConnSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    25
		flib_log_e("flib_ipcconn_listen: Already listening or connected.");
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    26
		return -1;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    27
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    28
	IPaddress addr;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    29
	addr.host = INADDR_ANY;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    30
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    31
	/* SDL_net does not seem to have a way to listen on a random unused port
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    32
	   and find out which port that is, so let's try to find one ourselves. */
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    33
	// TODO: Is socket binding fail-fast on all platforms?
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    34
	srand(time(NULL));
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    35
	rand();
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    36
	for(int i=0; i<1000; i++) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    37
		// IANA suggests using ports in the range 49152-65535 for things like this
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    38
		int ipcPort = 49152+(rand()%(65535-49152));
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    39
		SDLNet_Write16(ipcPort, &addr.port);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    40
		ipcListenSocket = SDLNet_TCP_Open(&addr);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    41
		if(!ipcListenSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    42
			flib_log_w("Failed to start an IPC listening socket on port %i: %s", ipcPort, SDLNet_GetError());
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    43
		} else {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    44
			flib_log_i("Listening for IPC connections on port %i.", ipcPort);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    45
			return ipcPort;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    46
		}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    47
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    48
	flib_log_e("Unable to find a free port for IPC.");
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    49
	return -1;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    50
}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    51
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    52
void flib_ipcconn_close() {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    53
	if(ipcListenSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    54
		SDLNet_TCP_Close(ipcListenSocket);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    55
		ipcListenSocket = NULL;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    56
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    57
	flib_nbsocket_close(&ipcConnSocket);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    58
	ipcReadBufferSize = 0;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    59
}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    60
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    61
IpcConnState flib_ipcconn_state() {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    62
	if(ipcConnSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    63
		return IPC_CONNECTED;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    64
	} else if(ipcListenSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    65
		return IPC_LISTENING;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    66
	} else {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    67
		return IPC_NOT_CONNECTED;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    68
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    69
}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    70
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    71
/**
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    72
 * Receive a single message and copy it into the data buffer.
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    73
 * Returns the length of the received message, -1 when nothing is received.
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    74
 */
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    75
int flib_ipcconn_recv_message(void *data) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    76
	flib_ipcconn_tick();
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    77
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    78
	if(ipcConnSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    79
		int size = flib_nbsocket_recv(ipcConnSocket, ipcReadBuffer+ipcReadBufferSize, sizeof(ipcReadBuffer)-ipcReadBufferSize);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    80
		if(size>=0) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    81
			ipcReadBufferSize += size;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    82
		} else {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    83
			flib_nbsocket_close(&ipcConnSocket);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    84
		}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    85
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    86
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    87
	int msgsize = ipcReadBuffer[0];
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    88
	if(ipcReadBufferSize > msgsize) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    89
		memcpy(data, ipcReadBuffer+1, msgsize);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    90
		memmove(ipcReadBuffer, ipcReadBuffer+msgsize+1, ipcReadBufferSize-(msgsize+1));
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    91
		ipcReadBufferSize -= (msgsize+1);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    92
		return msgsize;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    93
	} else if(!ipcConnSocket && ipcReadBufferSize>0) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    94
		flib_log_w("Last message from engine data stream is incomplete (received %u of %u bytes)", ipcReadBufferSize-1, msgsize);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    95
		ipcReadBufferSize = 0;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    96
		return -1;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    97
	} else {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    98
		return -1;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
    99
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   100
}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   101
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   102
int flib_ipcconn_send_message(void *data, size_t len) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   103
	flib_ipcconn_tick();
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   104
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   105
	if(!ipcConnSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   106
		flib_log_w("flib_ipcconn_send_message: Not connected.");
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   107
		return -1;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   108
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   109
	if(len>255) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   110
		flib_log_e("Attempt to send too much data to the engine in a single message.");
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   111
		return -1;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   112
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   113
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   114
	uint8_t sendbuf[256];
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   115
	sendbuf[0] = len;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   116
	memcpy(sendbuf+1, data, len);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   117
	if(flib_nbsocket_blocksend(ipcConnSocket, sendbuf, len+1) < len+1) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   118
		flib_log_w("Failed or incomplete ICP write: engine connection lost.");
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   119
		flib_nbsocket_close(&ipcConnSocket);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   120
		return -1;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   121
	} else {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   122
		return 0;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   123
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   124
}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   125
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   126
void flib_ipcconn_tick() {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   127
	if(!ipcConnSocket && ipcListenSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   128
		ipcConnSocket = flib_nbsocket_accept(ipcListenSocket, true);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   129
		if(ipcConnSocket) {
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   130
			SDLNet_TCP_Close(ipcListenSocket);
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   131
			ipcListenSocket = NULL;
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   132
		}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   133
	}
a0573014ff4f Further work on the frontend library, restructuring, ...
Medo <smaxein@googlemail.com>
parents:
diff changeset
   134
}