/* File: main.c
 * Desc: Main
 * Auth: Woody
 * Note: 
 */

//#define USE_SAY 1
//#define DO_HTML 1
#define	DO_XDIALOG 1
#include <termios.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>

#define BAUDRATE B115200
#define MODEMDEVICE "/dev/ttyS1"
#define LOGFILE "/tmp/phone.log"
#define _POSIX_SOURCE 1			/* POSIX compliant source */
#define MAX(a,b) ((a>b)?a:b)

#define deb(x) x
#define BUFFSIZE 256

extern int errno;
char *mytime ();

/*********************************************************************/

int 
main (argc, argv)
char **argv;
{
	int link_fd, log_fd, i, res, conf_fd;
	struct termios oldtio, newtio;
	char buff[BUFFSIZE];
	int buff_wait;
	char cmdline_buff[256];

	system ("clear");

	/* open the device to be non-blocking (read will return immediatly) */
	link_fd = open (MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
	if (link_fd < 0)
	{
		perror ("Open serial connection");
		exit (1);
	}

	log_fd = open (LOGFILE, O_RDWR | O_CREAT);
	if (log_fd < 0)
	{
		perror ("Open log file");
		exit (1);
	}
	i = lseek(log_fd,0,SEEK_END);	/* seek to the end == append */

	tcgetattr (link_fd, &oldtio);	/* save current port settings */
	/* set new port settings for non-canonical input processing */
	bzero (&newtio, sizeof (newtio));

	newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
	newtio.c_iflag = IGNBRK | INPCK | ICRNL;
	newtio.c_oflag = 0;
	newtio.c_lflag = 0;
	newtio.c_cc[VMIN] = 1;		// wait for up to 32 chars
	newtio.c_cc[VTIME] = 1;		// * 100 ms

	tcflush (link_fd, TCIOFLUSH);
	tcsetattr (link_fd, TCSANOW, &newtio);
	buff_wait = 0;

	write(link_fd, "AT#CID=1\r", 9);

	while (1)
	{
		struct timeval to;
		int I_rc;
		int	maxfd;
		fd_set readfds;

		to.tv_sec = 1;
		to.tv_usec = 0;
		FD_ZERO (&readfds);
		FD_SET (link_fd, &readfds);
		maxfd = link_fd + 1;

		if ((I_rc = select (maxfd, &readfds, 0, 0, &to)) < 0)
		{
			if (errno = EINTR)
				continue; /* We were interrupted by a signal... continue james... */
			perror ("select");
			exit (1);
		}
		else if (!I_rc) //no data within to.tv_sec sec
		{
dump_data_now:
			if(buff_wait)
			{
			char* p;
			
			    buff[buff_wait]=0;

			    /* replace all LFs with space */
			    p = buff;
			    while (*p)
			    {
				if (*p == 10)
				{
				    *p = ' ';
				}
				p++;
			    }
			    *p++ = 10;
			    *p = 0;
			    buff_wait++;

			    /* search for string 'DATE=' */
			    for (i=0; i<buff_wait; i++)
			    {
				if (buff[i]=='D' && buff[i+1]=='A' &&
				    buff[i+2]=='T' && buff[i+3]=='E' &&
				    buff[i+4]=='=')
				{
				    printf("%s",buff+i);
				    write(log_fd, buff + i, buff_wait-i);
				    fsync(log_fd);	/* flush buff */
#ifdef DO_HTML
				    system("/etc/ppp/phoned.sh");
#endif
				}
			    }
#ifdef USE_SAY
			    /* search for string 'NAME=' */
			    for (i=0; i<buff_wait; i++)
			    {
				if (buff[i]=='N' && buff[i+1]=='A' &&
				    buff[i+2]=='M' && buff[i+3]=='E' &&
				    buff[i+4]=='=')
				{
				    int j;
				    char name[16];

				    i += 5;
				    j = 0;
				    while ((j < 16) && (!(buff[i]==' ' && (buff[i+1]==' '))))
				    {
					name[j] = tolower(buff[i]);
					j++;
					i++;    
				    }
				    name[j] = 0;	/* terminate string */

				    /* prepare the say app string... */
				    sprintf(cmdline_buff,"/usr/local/bin/say '");
				    strcat(cmdline_buff, name);
				    strcat(cmdline_buff, "' > /dev/null");
//printf("say %s.\n",name);
				    system(cmdline_buff);
				}
			    }
#endif

#ifdef DO_XDIALOG
			    /* search for string 'NAME=' */
			    for (i=0; i<buff_wait; i++)
			    {
				if (buff[i]=='N' && buff[i+1]=='A' &&
				    buff[i+2]=='M' && buff[i+3]=='E' &&
				    buff[i+4]=='=')
				{

#if 0
				    int j;
				    char name[16];

				    i += 5;
				    j = 0;
				    while ((j < 16) && (!(buff[i]==' ' && (buff[i+1]==' '))))
				    {
					name[j] = tolower(buff[i]);
					j++;
					i++;    
				    }
				    name[j] = 0;	/* terminate string */
#endif
				    /* prepare the Xdialog app string... */
				    sprintf(cmdline_buff,"/usr/bin/Xdialog --title 'Caller ID' --no-button --infobox '");
				    strcat(cmdline_buff, &(buff[i]));
				    /* delete the closing LF and 2 spaces */
				    *(char*)(cmdline_buff + strlen(cmdline_buff) - 3) = 0;
				    strcat(cmdline_buff, "' 5 38 15000");
				    //printf("xdialog: %s.\n",cmdline_buff);
				    system(cmdline_buff);
				}
			    }
#endif
			    buff_wait = 0;
			}
			continue;
		}
		else if (FD_ISSET (link_fd, &readfds))
		{
			/* get COM data */
			//deb(printf("read(fd=%X,buff=%p,cnt=%d.\n",link_fd,buff+buff_wait,BUFFSIZE-buff_wait));
			i = read (link_fd, buff+buff_wait, BUFFSIZE-buff_wait);
			if (i < 0)
			{
				perror ("bad com data link");
				exit (1);
			}
			//deb(printf("got(%d)=%s",i,buff));
			buff_wait += i;	//so much data waiting...
			if (buff_wait == BUFFSIZE)
			    goto dump_data_now;
			continue;
		}
		else
		{
			printf("select() assert! failure");
			exit (1);
		}
	}
}

