/*
 * Socket.c
 *
 *  Created on: 17. Mai 2017
 *      Author: PirklbauerMa
 */

/* ========================================================================== */
/*                            Includes		                                  */
/* ========================================================================== */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/ndk/inc/bsd/sys/socket.h>
#include "ti/ndk/inc/bsd/socketndk.h"


// The following header should not be included referring to the NDK Reference Guide
// No header of the ti/ndk/inc should be included
/*
#include "ti/ndk/inc/socketndk.h"
#include "ti/ndk//inc/os/osif.h"
#include "ti/ndk/inc/usertype.h"
*/


/* ========================================================================== */
/*                            Constructors	                                  */
/* ========================================================================== */


void EchoTcpServer( IPN IPAddrLocal, IPN IPAddrExt )
{
	SOCKET s = INVALID_SOCKET;
	struct sockaddr sinExt;
	struct sockaddr_in sinLocal;
	int i, error, val, ret = 0;
	char *pBuf = 0;
	struct timeval timeout;
	char test[4096];

	// Allocate the file descriptor environment for this Task
	ret = fdOpenSession( (HANDLE)Task_self() );
	if (ret = 0)
	{
		System_printf("failed to create file descriptor session!");
		goto leave;
	}

	System_printf("\n== Start TCP Echo Server Test ==\n");
	// Create test socket
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);	// returns a file descriptor representing the socket
	if( s == INVALID_SOCKET ) // INVALID_SOCKET stands for -1
	{
		System_printf("failed socket create (%d)\n",fdError());
		goto leave;
	}
	// Prepare address for connect
	//bzero( &sinExt, sizeof(struct sockaddr_in) );
	//sinExt.sin_family = AF_INET;
	//inet_aton("192.168.1.10", &sinExt.sin_addr.s_addr); // Var.1 to set IP Addr. PC
	//sinExt.sin_addr.s_addr = IPAddrExt;	// Var.2 to set IP Addr. PC
	//sinExt.sin_port = htons(54216); // Port PC
	// Prepare address for listening
	bzero( &sinLocal, sizeof(struct sockaddr_in) );
	sinLocal.sin_family = AF_INET;
	//inet_aton("192.168.1.4", &sinLocal.sin_addr.s_addr); // Var.1 to set IP Addr. ICEV2
	sinLocal.sin_addr.s_addr = IPAddrLocal; // Var.2 to set IP Addr. ICEV2
	sinLocal.sin_port = htons(23); // Port ICEV2
	//sinExt.sin_port = htons(7); // Port ICEV2

	// Configure our Tx and Rx timeout to be 5 seconds
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;
	// Set send timeout
	ret = setsockopt( s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof( timeout ) );
	if (ret < 0 )
	{
		System_printf("failed set socket option (%d)\n",fdError());
		goto leave;
	}
	// Set receive timeout
	ret = setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof( timeout ) );
	if (ret < 0 )
	{
		System_printf("failed set socket option (%d)\n",fdError());
		goto leave;
	}

	// [PIM 20170522] Test bind() function for a port
	ret = bind( s, (PSA) &sinLocal, sizeof(sinLocal));
	if( ret < 0 )
	{
		System_printf("failed to bind port (%d)\n",fdError());
		goto leave;
	}
	// [PIM 20170522] Test listen() function for a port
	ret = listen( s, 10);
	if( ret < 0 )
	{
		System_printf("failed to listen (%d)\n",fdError());
		goto leave;
	}
	// [PIM 20170522] Test accept() function for a port
	ret = accept( s , &sinExt, sizeof(sinExt));	// writes address from connecting entity in sinExt
	if( ret < 0 )
	{
		System_printf("failed to accept (%d)\n",fdError());
		goto leave;
	}
	goto leave;

leave:
	if( pBuf )
		free( pBuf );
	if( s != INVALID_SOCKET )
		fdClose( s );
	System_printf("== End TCP Echo Server Test ==\n\n");

	// Free the file descriptor environment for this Task
	fdCloseSession( (HANDLE)Task_self() );

}


