/*
 * Author:
 *         Kendy Kutzner <kutzner@ira.uka.de>
 *
 * (c) 2005 Research Group Dr. Fuhrmann, University of Karlsruhe, Germany
 * All rights reserved.
 *
 * $Id: testmulticlient.cc,v 1.5 2006/02/05 15:38:52 kutzner Exp $
 *
 */

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <pthread.h>
#include <stdlib.h>
#include "libigor.h"
#include "utils.h"

// global socket
int s;
// global number of sent/received msg
int received;
int sent;
int recvstat[256];

void topen(){
	s = igor_socket();
	printf("socket(%i): %s\n", s, igor_strerror(s));
}

void tbind(){
	struct igor_apptype at;
	at.apptype = "foo";
	at.len = strlen(at.apptype);
	at.mustbehashed = 1;
	int bindres = igor_bind(s, &at);
	printf("bind(%i): %s\n", bindres, igor_strerror(s));
}

void tsend(){
	struct sa_igor sa;
	int * randfield = (int*)malloc (sizeof(int)*5);
	for (int i = 0; i < 5 ; i++){
		randfield[i]=random();
	}
	sa.address = (const char*)(&(randfield[0]));
	sa.len = 5*sizeof(int);
	sa.mustbehashed = 1;
	double msg = dbltime();
	bool upcall = false;
	/*int sendtores = */igor_sendto(s, &msg, sizeof(double), upcall, &sa);
	//printf("sendto(%i): %s\n", sendtores, igor_strerror(s));
	sent++;
}

void trecv(){
	size_t len;
	bool upcall;
	struct sa_igor src;
	struct sa_igor dst;
	src.len=0;
	dst.len=0;
	void * msg = NULL;
	int recvres = igor_recvfromto(s, &msg, &len, &upcall, &dst, &src);
	//printf("recv(%i): %s\n", recvres, igor_strerror(s));
	if(IGOR_ERR_NOERR == recvres){
		int i;
		printf("recv: res %i len %i upcall %i ", recvres, len, upcall);
		printf(" src ");
		i = 0;
		//for (i = 0 ; i < src.len; i++)
		//printf("%02hhx", src.address[i]);
		printf("%02hx", src.address[i]);
		printf(" dst ");
		for (i = 0 ; i < dst.len; i++)
//			printf("%02hhx", dst.address[i]);
			printf("%02hx", dst.address[i]);
		double now = dbltime();
		printf(" delay %f\n", now - *((double*)(msg)));
		//printf(" using byte %02hhx\n", dst.address[3]);
		recvstat[0xff&dst.address[3]]++;
	}
	received++;
}

void tclose(){
	int closeres = igor_close(s);
	printf("close(%i): %s\n", closeres, igor_strerror(s));
}

void *
recv_thread(void*){
	while(true){
		trecv();
	}
}

int main(int /*argc*/, char * /*argv[]*/){
	srand(time(NULL));
	sent=0;
	received=0;
	int i;
	for (i = 0; i< 256 ; i++)
		recvstat[i] = 0;
	topen();
	tbind();
	pthread_t t;
	pthread_create(&t, NULL, recv_thread, NULL);
	int counter = 0;
	while (true){
		counter++;
		tsend();
		if ((sent-received) > 1)
			usleep(10000000);
		if (!((received+1)%100)){
			printf("\n");
			for (i=0; i< 256 ; i++){
				printf("%2.2x:%2i ", i, recvstat[i]);
				if(!((i+1)%16)) printf("\n");
			}
			printf("\n");
		}
	}
}
