#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 ];                     /* komunikat */
	struct timeval tv;                    /* czas */
	struct sockaddr_in hblisten;          /* struktura adresowa serwera */
   int hblistenlen = sizeof( hblisten );
	int sdata;                            /* gniazdo do przesylania danych */
	int shb;                              /* gniazdo połączone dla heartbeat */
	int slisten;                          /* gniazdo nasluchujące
                                            dla połączenia heartbeat */
   int rc;
   int heartbeats = 0;
	int maxfd1;
	char hbmsg[ 1 ];

	program_name=argv[0];

   /* Przypisz hostowi port efemeryczny */
	slisten = tcp_server( NULL, "0" );
   /* Pobierz dane o przydzielonym porcie */
	rc = getsockname( slisten, ( struct sockaddr * )&hblisten,
		                          &hblistenlen );
	if ( rc )
		error( 1, errno, "getsockname()" );

   /* Nawiąż połączenie z serwerem i przeslij mu numer portu hearbeat */
	sdata = tcp_client( argv[ 1 ], argv[ 2 ] );
	rc = write(sdata, (char *)&hblisten.sin_port, sizeof(hblisten.sin_port));
	if ( rc < 0 )
		error( 1, errno, "write()" );
   /* Czekaj, az serwer ustanowi połączenie heartbeat */
	shb = accept( slisten, NULL, NULL );
	if ( shb <=0 )
		error( 1, errno, "accept()" );

	FD_ZERO( &afd );
	FD_SET( sdata, &afd );               /* dodaj gniazdo danych */
	FD_SET( shb, &afd );                 /* dodaj gniazdo heartbeat */
	maxfd1 = ( sdata > shb ? sdata: shb ) + 1;
	tv.tv_sec = T1;
	tv.tv_usec = 0;

	for ( ;; )
	{
		readfd = afd;
		rc = select( maxfd1, &readfd, NULL, NULL, &tv );
		if ( rc < 0 )
			error( 1, errno, "select()" );
		if ( rc == 0 )		/* timed out */
		{
			if ( ++heartbeats > 3 )
				error( 1, 0, "martwe połączenie\n" );
			error( 0, 0, "wysylam heartbeat nr %d\n", heartbeats );
			rc = write( shb, "", 1);
			if ( rc < 0 )
				error( 1, errno, "write()" );
			tv.tv_sec = T2;
			continue;
		}
		if ( FD_ISSET( shb, &readfd ) )
		{
			rc = read( shb, hbmsg, 1);
			if ( rc == 0 )
				error( 1, 0, "Serwer zakoczyl prace (shb)\n" );
			if ( rc < 0 )
				error( 1, errno, "blad read w shb" );
		}
		if ( FD_ISSET( sdata, &readfd ) )
		{
			rc = read( sdata, msg, sizeof( msg ) );
			if ( rc == 0 )
				error( 1, 0, "Serwer zakoczyl prace (sdata)\n" );
			if ( rc < 0 )
				error( 1, errno, "read()" );

			/* przetwarzaj dane */
		}
		heartbeats = 0;
		tv.tv_sec = T1;
	}
}

