/*
 * net.c
 *
 * This code was stolen from Andy Warner's original net.c (UNIX)
 * Very minor changes made it winsock2 compatible - 3.25.98 TPS
 *
 *
 * kgs is a server that sits between gdb and the KME interface to an
 * EPC host adapter.
 *
 * This file contains the network dependant code.
 */


#include <winsock2.h>
#include <io.h>

//#include "net.h"

/*
 * Open the required socket, and wait until someone connects
 * to it, working on the principle that the board can do what it likes
 * until there is a debugger ready to talk to it.
 *
 * Return the descriptor (>= 0) iff OK, -1 (with errno set) on error.
 */
int
OpenSocket(int port)
{
	int s, ns, Temp ;
	struct sockaddr_in Local, Remote ;
	size_t RemoteSize ;
	struct protoent *Proto ;

	Proto = getprotobyname("tcp") ;
	if (!Proto) {
		return(-1) ;
	}

	/*
	 * Create the socket.
	 */
	if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		return(s) ;
	}

	/*
	 * Enable speedy re-use of this port.
	 */
	Temp = 1 ;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&Temp, sizeof(Temp)) ;

	/*
	 * Bind it to the port number specified.
	 */
	memset(&Local, 0, sizeof(Local)) ;
	Local.sin_family = AF_INET ;
	Local.sin_port = htons((WORD)port) ;
	Local.sin_addr.s_addr = htonl(INADDR_ANY) ;


	if (bind(s, (struct sockaddr *)(&Local), sizeof(Local)) == -1) {
		_close(s) ;
		return(-1) ;
	}

	/*
	 * Wait for incoming connections..
	 */
	if (listen(s, 1) == -1) {
		_close(s) ;
		return(-1) ;
	}

	RemoteSize = sizeof(Remote) ;
	if ((ns = accept(s, (struct sockaddr *)&Remote, &RemoteSize)) == -1) {
		_close(s) ;
		return(-1) ;
	}

	_close(s) ;

	/*
	 * Enable keepalives and minimal delay..
	 */
	Temp = 1 ;
	setsockopt(ns, SOL_SOCKET, SO_KEEPALIVE, (char *)&Temp, sizeof(Temp)) ;
	Temp = 1 ;
	setsockopt(ns, Proto->p_proto, TCP_NODELAY, (char *)&Temp, sizeof(Temp)) ;

	return(ns) ;
}

void
CloseSocket(int s)
{
	shutdown(s, 2) ;
	_close(s) ;
}
