#include "tcp.h"
#include "heartbeat.h"

int main( int argc, char **argv )
{
	fd_set afd;                    /* wszystkie deskryptory */
	fd_set readfd;                 /* deskryptory robocze */
	char msg[ 1024 ];
	struct sockaddr_in client;     /* stuktura adresowa klienta */
  	int clientlen = sizeof( client );
	struct timeval tv;             /* czas */
	int s;                         /* gniazdo nasłuchujące serwera */
	int sdata;                     /* gniazdo połączone klienta */
	int shb;                       /* gniazdo do przesyłania heartbeat'ów */
	int rc;
	int maxfd1;
	int missed_heartbeats = 0;

	char hbmsg[ 1 ];

	program_name=argv[0];

   /* Ustaw gniazdo nasłuchujące */
	s = tcp_server( NULL, argv[ 1 ] );
   /* Czekaj na zgłosznie klienta */
	sdata = accept( s, ( struct sockaddr * )&client,
		&clientlen );
	if ( sdata <= 0  )
		error( 1, errno, "accept()" );
	rc = readn( sdata, ( char * )&client.sin_port,
		sizeof( client.sin_port ) );
	if ( rc < 0 )
		error( 1, errno, "blad przy czytaniu numeru portu" );

   /* Utwórz gniazdo dla heartbeat */
	shb = socket( PF_INET, SOCK_STREAM, 0 );
	if ( shb<=0  )
		error( 1, errno, "socket() dla shb" );
	rc = connect( shb, ( struct sockaddr * )&client, clientlen );
	if ( rc )
		error( 1, errno, "connect() dla shb" );

	tv.tv_sec = T1 + T2;
	tv.tv_usec = 0;
	FD_ZERO( &afd );
	FD_SET( sdata, &afd );
	FD_SET( shb, &afd );
	maxfd1 = ( sdata > shb ? sdata : shb ) + 1;

	for ( ;; )
	{
		readfd = afd;
		rc = select( maxfd1, &readfd, NULL, NULL, &tv );
		if ( rc < 0 )
			error( 1, errno, "select()" );
		if ( rc == 0 )		/* timed out */
		{
			if ( ++missed_heartbeats > 3 )
				error( 1, 0, "martwe polaczenie\n" );
			error( 0, 0, "brak sygnalu heartbeat nr %d\n",
				missed_heartbeats );
			tv.tv_sec = T2;
			continue;
		}

		if ( FD_ISSET( shb, &readfd ) )
		{
			rc = read( shb, hbmsg, 1 );
			if ( rc == 0 )
				error( 1, 0, "Klient zakonczyl prace\n" );
			if ( rc < 0 )
				error( 1, errno, "read() dla shb" );
			rc = write( shb, hbmsg, 1 );
			if ( rc < 0 )
				error( 1, errno, "write() dla shb" );
		}

		if ( FD_ISSET( sdata, &readfd ) )
		{
			rc = read( sdata, msg, sizeof( msg ) );
			if ( rc == 0 )
				error( 1, 0, "Klient zakonczyl prace\n" );
			if ( rc < 0 )
				error( 1, errno, "read()" );

			/* przetwarzanie danych */
		}

		missed_heartbeats = 0;
		tv.tv_sec = T1 + T2;
	}
	exit( 0 );
}

