/******************************************************** 
 *                 SWD.MOD.037/101 
 * 
 * File:           ubeam.c 
 *
 * P.N.:           ESWP-DTIUS-APP 
 * 
 * Rel.:           2.0.0 
 *
 * Product:        Data Transfer Interface Unit (DTIU) for the HORIZON program  *
 * Property:       Ele.Si.A. s.r.l. - All rights reserved 
 *
 * Author:         Fabio Garufi
 * 
 * Creation Date:  May 16, 2002 
 *
 * Description: 
 * 	Program to test TCP/IP socket (sender)
 * 
 * Revisions History: 
 *
 *
 ********************************************************/

#include <sys/types.h>
#ifdef LINUX
#include <linux/socket.h>
#else
#include <socket.h>
#endif
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#ifdef LYNXOS
#include <bsd/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#endif
#include <math.h>
void send_cli(int sock, int n, int size);
unsigned int tvsub(struct timeval * t1,  struct timeval * t0);

#define PORT 12345
int main(int argc, char **argv)
{
  int sockfd;
  int n;
  int size; 
  int port=PORT;
  struct sockaddr_in servAddr;
  if (argc < 4)
    {
      printf("usage: %s <IP Address> <messages> <size> [<port>]\n", __FILE__);
      return -1;
    }

  if(argc == 5)
    port = (u_short)atoi(argv[4]); 
  n = atoi(argv[2]);
  size = atoi(argv[3]);
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  bzero(&servAddr, sizeof(servAddr));
  servAddr.sin_family = AF_INET;

  servAddr.sin_port=htons(port);
  servAddr.sin_addr.s_addr = inet_addr(argv[1]);
  connect(sockfd, (struct sockaddr *)&servAddr, sizeof(struct sockaddr));
  send_cli(sockfd, n, size);
  return 0;
}



void send_cli(int sock, int n, int size)
{
  int i;
  char *buf;
  char end=0;
  struct timeval start, stop;
  struct timeval p_start, p_stop;
  u_long p_delta;
  u_long min=10000000, max=0;
  int lost;
  int out=0, index[100],idx=0;
  float avg, sigma, sum=0, sum2=0;
  float msgsec;
  u_long DeltaT;
  buf = (char *)malloc(size);
  memset((char *)buf, 0xA, size);
  if(send(sock, (char *)buf, size, 0) <0)
    perror("send: ");
  
  gettimeofday(&start, 0);
  for (i =0; i<n; i++)
    {
      gettimeofday(&p_start, 0);
      if(send(sock, (char *)buf, size, 0) <0)
	perror("send: ");
      
      
      while (read(sock, &end, 1)  == 0) ;
      if(end != 0xe)
	{
	  printf("not acknowledged\n");
	  return;
	}
      gettimeofday(&p_stop,0);
      p_delta= tvsub (&p_stop, &p_start);
      p_delta < min ? min = p_delta : min;
      p_delta > max ? max = p_delta : max;
      if( p_delta > 50000)
	{
	  out ++; 
	  index[idx]=p_delta;
	  idx++;
	}
      sum += p_delta;
      sum2 += (p_delta * p_delta);
}
  
  gettimeofday (&stop, 0);
  avg=((float)sum/(float)n);
  sigma = (sum2/(float)n) - (float)(avg*avg);
  sigma = sqrt(sigma);
  DeltaT=tvsub(&stop, &start);
  printf(" out %d\n", out); 
  for(i = 0; i< out;i++)printf("index[%d] %d ", i, index[i]);
  printf("min %d \t max %d\n", min, max);
  printf("sum %f sum2 %f\n",sum, sum2);
  printf(" Avg. %f\t Sigma %f \n", avg, sigma);
  printf(" Delta T = %d (usec)\n",DeltaT);
  msgsec = (1000000.0*n)/((float)DeltaT);
  printf(" %f messages/sec\n", msgsec);
}



unsigned int tvsub(struct timeval * t1, 
                   struct timeval * t0)
{
  unsigned int res;
  unsigned int aux;
  
  aux = t1->tv_sec - t0->tv_sec;
  if (aux > 0) {
  /* res = (aux - 1) * 1000000 + t1->tv_usec + 1000000 - t0->tv_usec; */
    res = aux * 1000000 + t1->tv_usec - t0->tv_usec;
  }
  else {
    res = t1->tv_usec - t0->tv_usec;
  } /* end if */	
  
  return(res);              
} /* end of tvsub */


