/*---------------------------------------------------------------------------*\

	FILE....: cidg2test.cpp
	TYPE....: C Program
	AUTHOR..: Peter Wintulich
	DATE....: 12/11/02

	Test program for type 2 Caller ID transmit
	

	Compile: gcc cidg2test.cpp cidg.cpp -o cidgtest -lvpb -lm -pthread -Wall

\---------------------------------------------------------------------------*/

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

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
//#include "verbose.h"


int class_t2_out(int h, const char *num, const char *text);
int ctwaitforevent(int h, int event_type, int timeout_ms);


int main(int argc, char *argv[])
{
	int	h;			// vpb channel handle
	int     ch_num;			// channel #
	char	number[50];
	char	txtmessage[50];

	//verbose(1);

	if (argc == 1) {
	    printf("Usage: ./cidg2test <Ch[0..]> \n");
		exit(0);
	}

	strcpy(number,"82321502");
	strcpy(txtmessage,"Voicetronix");

	ch_num = atoi(argv[1]);
	h = vpb_open(0, ch_num);

	//XXX vpb_record_file_async(h, "./zout.wav", VPB_LINEAR);
	sleep(1);

	//char num[]= "123456789012345";
	//char text[]="ABCDEFGH";
	//char num[]= "666666666";
	class_t2_out(h, "1", "ONE");
	sleep(3);
	class_t2_out(h, "12", "TWO");
	sleep(3);
	class_t2_out(h, "123", "Three");
	sleep(3);
	class_t2_out(h, "1234", "Four");
	sleep(3);
	class_t2_out(h, "12345678", "Eight");
	sleep(3);
	vpb_close(h);
	return 0;
}


/*-----------------------------------------------------------------------\
	FUNCTION: class_t2_out(....)
	This function sends the Type II call waiting CID. It uses the data
	struct VPB_DLP.	

	FLOW:
	1) (OPTIONAL)	send 300ms of 440Hz tone. To alert caller of incoming 
			Call Waiting CID.
	2)		50ms silence
	3)		100ms of Dual tone 2130 & 2750 at -10dB 
	4)		Wait for 200ms for DTMF A or D reply,
			If no reply inside 200ms terminate, else 5)
	5)		transmit C.W.CID wave
	6)		50ms silence

\-----------------------------------------------------------------------*/
int class_t2_out(int h, const char *num, const char *text)
{
	VPB_CID 	didcw;
	char		VPB_DLP[VPB_CID_MAX_DLP];	// Datalink Layer 
	int		ev;
	int		n, x;
	short   	*buf;		// wave holding buffer
	short   	*cas;		// wave holding buffer
	short   	*sas;		// wave holding buffer
	short   	*sil;		// wave holding buffer
	int		buff_count=0;	// active word count in buf

	buf = (short*)calloc(sizeof(short),20000);	// CID Wave Buffer
	cas = (short*)calloc(sizeof(short),1200);	// 50+100ms CAS Buffer
	sas = (short*)calloc(sizeof(short),2400);	// 300ms SAS Buffer
	sil = (short*)calloc(sizeof(short),400);	// 50ms silence

	if(buf == NULL || cas == NULL || sas == NULL)
		return -1;		// One of the malloc's failed quit

	// compose message
	// Initialise fields
	if(vpb_cid_set(&didcw,VPB_CID_CALLING_LINE_DN,(void *)num))
		printf("failed set calling line\n");
	if(vpb_cid_set(&didcw,VPB_CID_CALLER_NAME,(void *)text))
		printf("failed set caller name\n");

	n = vpb_cid_compose_dlp(&didcw, VPB_DLP);
	vpb_cid_t2_compose_wav(VPB_DLP, n, buf, &buff_count);
	printf("buf count: %d\n", buff_count);

	vpb_play_buf_start(h, VPB_LINEAR);

    #if 0
	printf("cidcw\n");
	// send SAS == 440mhz (300ms in length)
	for(x=0; x < 2400; ++x)
		*(sas+x) =(short)( cos(2*3.14159/8000*x*440)*1000);

	vpb_play_buf_sync(h, (char*)sil, 400*2);
	vpb_play_buf_sync(h, (char*)sas, 2400*2);
	vpb_play_buf_sync(h, (char*)sil, 400*2);
    #endif

	printf("send CAS\n");
	// send CAS == 2030+2750 (DTMF)
	// NOTE: UK(BT) uses 2130&2750 twist 7dB for 88to110ms
	// NOTE: Skip first 400 samples (50ms) to leave as silence
	for(x=400 ; x<1200; x++) {
		cas[x] =(short)((sin((2*M_PI/8000)*x*2130)+sin((2*M_PI/8000)*x*2750))*1000);
	}
	vpb_play_buf_sync(h, (char*)cas, 1200*2);
	vpb_play_buf_sync(h, (char*)sil, 400*2);
	vpb_play_buf_sync(h, (char*)sil, 400*2);
	vpb_play_buf_sync(h, (char*)sil, 400*2);

	printf("Waiting on ACK\n");
	// Ack ACK == "A" or "D";  A == 941+1633hz, D == 697+1633Hz
	ev = ctwaitforevent(h, VPB_DTMF, 500);
	if(ev == VPB_DTMF) {
		// send cid_t2_packet
		printf("Sending composed CID\n");
		vpb_play_buf_sync(h, (char*)buf, buff_count*2);	// CID Data
	}
	vpb_play_buf_finish_sync(h);
	printf("Done.\n");
	free(buf);
	free(cas);
	free(sas);
	// if X == 0 then no ACK from the CAS
	// if X == -1 then one or more malloc failed
	// Ready for normal ring process
	return x;
}

int ctwaitforevent(int h, int event_type, int timeout_ms) {
	char      s[VPB_MAX_STR];
	int       ret, state;
	VPB_EVENT e;
	void      *timer;

	vpb_timer_open(&timer, h, 0, timeout_ms);
	if (timeout_ms != 0)
		vpb_timer_start(timer);

	state = 1;
	while(state) {
		ret = vpb_get_event_ch_async(h, &e);

		if (ret == VPB_OK) {
			vpb_translate_event(&e, s);
			printf("%s",s);

			if (e.type == event_type) {
				state = 0;
			}
			if (e.type == VPB_TIMEREXP) {
				state = 0;
			}
			//if(e.type == VPB_STATION_OFFHOOK) { state = 0; }
		}
		else
			vpb_sleep(100);
	}

	vpb_timer_close(timer);
	if (state == 0)
		return e.type;
	else
		return -1;
}
