/*
  tcutthru.cpp
  David Rowe 28/8/02

  Tests cut thru performance of dtmf detector.  Can be configured to
  work with the OpenSwitch or OpenLine cards.   Can use internally
  generated tone or external wave file as the "prompt" to be played.

  With the OpenLine cards a PBX or skutch box is needed to bridge the 
  two ports.  With the OpenSwitch card a station port can be connected
  directly to a loop start port.

*/

#include "../kbhit.h"
#include "vpbapi.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>

VPB_TONE DialTone = { 450, 425, 400, -10,   -10,  -10, 10000, 0 };

#define TEST_DIGITS 24


static int arg_exists(int argc, char *argv[], const char *arg)
{ //{{{
	for(int i = 0; i < argc; ++i)
		if(strcmp(argv[i],arg) == 0) return i;

	return 0;
} //}}}

int main(int argc, char *argv[]) {
	int       hs, hl, ret, arg;
	VPB_EVENT e;
	char      s[VPB_MAX_STR];
	int       digits_rx;
	int       digits_tx;
	float     percent;
	int       sendport, listenport;
	char      *wave;
	float     gain;

	if (arg_exists(argc, argv, "-h")) {
		printf("usage: tcutthru\n"
		       "--sendport SendPort[0...]\n"
		       "--listenport ListenPort[0...]\n"
		       "--wave   WaveFile\n"
		       );
		exit(0);
	}

	sendport = 0; listenport = 8;

	// optionally change default ports
	if ((arg = arg_exists(argc, argv, "--sendport")) != 0) {
		sendport = atoi(argv[arg+1]);
		printf("Send port set to %d\n", sendport);
	}
	if ((arg = arg_exists(argc, argv, "--listenport")) != 0) {
		listenport = atoi(argv[arg+1]);
		printf("Listen port set to %d\n", listenport);
	}

	hs = vpb_open(0,sendport);
	hl = vpb_open(0,listenport);
	vpb_sethook_sync(hl, VPB_OFFHOOK);
	vpb_sethook_sync(hs, VPB_OFFHOOK); // only for OpenLine4
	digits_tx = 0;
	digits_rx = 0;

	// optionally adjust gains
	if ((arg = arg_exists(argc, argv, "--recgain")) != 0) {
		vpb_record_set_hw_gain(hs, (float)atof(argv[arg+1]));
		printf("record gain set to %f\n", atof(argv[arg+1]));
	}
	vpb_record_get_gain(hs, &gain);
	printf("Record: gain = %f\n", gain);

	// optionally set play gain - used for gain testing
	if ((arg = arg_exists(argc, argv, "--playgain")) != 0) {
		vpb_play_set_hw_gain(hs, (float)atof(argv[arg+1]));
		printf("play gain set to %f\n", atof(argv[arg+1]));
	}
	vpb_play_get_gain(hs, &gain);
	printf("Play: gain = %f\n", gain);

	if ((arg = arg_exists(argc, argv, "--recwav")) != 0) {
		vpb_record_file_async(hs, argv[arg+1], VPB_LINEAR);
		printf("recording to %s\n", argv[arg+1]);
	}

	// optionally set wave file as "prompt" rather than tone

	if ((arg = arg_exists(argc, argv, "--wave")) != 0) {
		wave = argv[arg+1];
	}
	else
		wave = NULL;

	// start the ball rolling
	if (wave == NULL) {
		//vpb_playtone_async(hs, &DialTone);	
	} else {
		vpb_play_file_async(hs, wave, 0);
	}

	vpb_dial_async(hl, "1234567890#*,");

	do {
		ret = vpb_get_event_async(&e);
		if (ret == VPB_OK) {
			vpb_translate_event(&e, s);

			if (e.handle == hs) {
				if (e.type == VPB_DIALEND) {
					// tone finished so start again
					vpb_playtone_async(hs, &DialTone);
				}
				if (e.type == VPB_PLAYEND) {
					// file finished so start again
					vpb_play_file_sync(hs, wave);
				}
				if (e.type == VPB_DTMF) {
					digits_rx++;
				}
			}

			if (e.handle == hl) {
				if (e.type == VPB_DIALEND) {
					// DTMFs finished so start again
					digits_tx += 12;
					vpb_dial_async(hl, "1234567890#*,");
					percent = 100.0*(float)digits_rx/digits_tx;
					printf("tx: %d rx: %d %3.2f%%\n",
					       digits_tx, digits_rx, percent);
				}
			}
		}
		vpb_sleep(10);

	} while(digits_tx < TEST_DIGITS);

	vpb_record_terminate(hs);

	if (wave == NULL) {
		vpb_tone_terminate(hs);
	} else {
		vpb_play_terminate(hs);
	}

	vpb_sleep(500);

	vpb_sethook_sync(hl, VPB_ONHOOK);
	vpb_close(hs);
	vpb_close(hl);

	return 0;
}

