
/* Copyright (C) 1993 Free Software Association of Germany

   The following is only valid, if you use this outside the Federal
   Republic of Germany.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   If you don't have a a copy of the GNU General Public License
   write to the Free Software Foundation, Inc., 675 Mass Ave, 
   Cambridge, MA 02139, USA.

   (C)opyright 1993,1994 FREE SOFTWARE ASSOCIATION OF GERMANY

   ----------------------------------------------------------------

   Fuer die Nutzung dieses Quell-Codes innerhalb der Bundesrepublik
   Deutschland gilt:

   Dieses Programm ist freie Software und kann unter den Bedingungen
   der Deutschen Free Software Lizenz weitergeben und/oder modifiziert
   werden.

   Wir haben dieses Programm in der Hoffnung entwickelt, dass es
   sich als nuetzlich erweist. Wir uebernehmen jedoch *KEINERLEI*
   Garantien auf die Funktion oder Verwendbarkeit dieses Programms.
   Der Anwender nutzt dieses Programm * AUF EIGENES RISIKO *

   Diesem Programm sollte eine Kopie der Deutschen Free Software Lizenz
   (DFSL) beigefuegt sein. Falls nicht, kann eine Kopie von uns angefordert
   werden: Free Software Association of Germany, Heimatring 19,
   60596 Frankfurt (info@elara.fsag..de), Telefon: ++49 - 69 - 6312083

   (C)opyright 1993,1994 FREE SOFTWARE ASSOCIATION OF GERMANY */


#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/soundcard.h>
#include <linux/time.h>
#include <time.h>
#include "gsm.h"
#include "ulaw.h"

#define AUDIO "/dev/audio"
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif

struct sockaddr_in	tcp_srv_addr;
struct sockaddr_in	myctladdr;
struct sockaddr_in	data_addr;
struct servent		tcp_serv_info;
struct hostent		tcp_host_info;

char current_ip[100];
char host[100];
int great_errno; 



#ifndef lint
static	char copyright[] =
"@(#) Copyright (c) 1993, 1994 Free Software Association of Germany.\n";
#endif

#ifndef lint
static char sccsid[] = "@(#) mtalk  Version 0.90 Fri 25 Mar 1994 15:37\n";
#endif 
    

#ifndef FD_SETSIZE
/* Forward compatability */
#define FD_SET(n, p)    ((p)->fds_bits[0] |= (1<<(n)))
#define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1<<(n)))
#define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1<<(n)))
#define FD_ZERO(p)      ((p)->fds_bits[0] = 0)
#endif

int GSM = 1;
int ANT = 0;
int PORT;
int DEBUG;

unsigned char *out_buff=NULL;
int o_b = 0;


main(int argc, char **argv)
{
	fd_set readfds;
        struct timeval timeout;
	FILE *fp;
	int a,b,hd;
	int cnt,ccnt;
	char c;
	int broken;
	char tmp[200];
	unsigned char mbuf[512];
	int au1,au2;	
	gsm handle;
        gsm_frame buf;
        gsm_signal sample[160];
	int ou;

	PORT=5101;
	DEBUG = 0;
	host[0] = 0;

	if (argc <= 1)
		dhelp();

	for (a = 1; a < argc; a++)	{
		if (!strcmp(argv[a],"-?"))
			dhelp();
		if (!strcmp(argv[a],"-d"))	{
			DEBUG = 1;
			continue;
			}
		if (!strcmp(argv[a],"-last"))	{
			ANT = 1;
			continue;
			}
		if (!strcmp(argv[a],"-8"))	{
			GSM = 0;
			continue;
			}
		if (!strcmp(argv[a],"-term"))	{
			PORT=5102;
			continue;
			}
		strcpy(host,argv[a]);
		}

	if (ANT == 1)	{
		fp = fopen("/tmp/mtalk.user","r");
		fgets(host,150,fp);
		fclose(fp);
		if (host[strlen(host)-1] == 10)
			host[strlen(host)-1] = 0;
		}

	if (GSM == 1)	{
		if (!(handle = gsm_create()))   {
			printf("mtalk: Unable to create a gsm handle\n");
			exit(1);
			}
		}

	if (host[0] == 0)	{
		printf("mtalk: must specify hostname\n");
		exit(0);
		}

	while (1)	{
		broken = 0;
		printf("mtalk: To %s: Hit [RETURN] to start your message\n",host);
		getchar(); 
		hd = open("/dev/audio",O_RDONLY);
		if (hd < 0)	{
			printf("mtalk: Unable to open /dev/audio\n");	
			exit(0);
			}
		ccnt = cnt = ou = au1 = au2 = 0;
		printf("mtalk: Recording.....\n");
		while (1)	{
			FD_ZERO(&readfds);
			FD_SET(0,&readfds);
			b = select(1,&readfds,(fd_set*)0,(fd_set *)0, &timeout);
			if (b > 0)	{
				printf("mtalk: wait - syncing buffers...\n");
				read(0,&c,1);
				broken = 1;
				}
			a = read(hd,mbuf,160);
	                if (a != 160)
	                        break;
			au1+=a;
			if (GSM == 1)	{
				if (broken == 0)
					ccnt++;
	           		for (a = 0; a < 160; a++)       
					sample[a] = U2S(mbuf[a]); 
				gsm_encode(handle,sample,buf);
				addout(buf,sizeof(buf));
				}
			else
				addout(mbuf,160);

			if (broken == 1)	{
				cnt++;
				if (cnt >= ccnt)
					break;
				}
			}
		if (DEBUG == 1)	{
			printf("\nmtalk: Record size: %d\n",au1);
			printf("mtalk: Compressed : %d\n",o_b);
			}
		printf("mtalk: Connecting to host %s\n",host);
		hd = gl_tcp_open(host,NULL,PORT);
		if (hd < 0)	{
			printf("mtalk: Unable to connect to %s\n",host);
			exit(0);
			}
		read_line(hd,tmp);
		if (DEBUG == 1)
			printf("[%s]\n",tmp);
		else
			printf("Connected\n");
		if (GSM == 1)
			write(hd,"002 1\r\n",7);
		else
			write(hd,"002 0\r\n",7);
		read_line(hd,tmp);
		if (DEBUG == 1)
			printf("[%s]\n",tmp);
		sprintf(tmp,"003 %d\n",o_b);
		write(hd,tmp,strlen(tmp));
		read_line(hd,tmp);
		if (DEBUG == 1)
			printf("[%s]\n",tmp);
		a = slow_write(hd,out_buff,o_b);
		read_line(hd,tmp);
		if (DEBUG == 1)
			printf("[%s]\n",tmp);
		exit(1);	
		}

}

addout(char *s, int sz) 
{
	int a;
	int calc;

	if (out_buff == NULL)
		out_buff = (unsigned char *)malloc(200000);

	for (a = 0; a < sz; a++)
		out_buff[o_b++] = s[a];

	calc = (o_b / 1000) / 2;
	printf("> %03d %\r",calc);
	fflush(stdout);
}


	

read_line(int hd,char *s)
{
	int la = 0;
	int a;
	unsigned char c;

	for (a = 0; a < 512; a++)	{
		if (read(hd,&c,1) != 1) 	{
			printf("mtalk: Remote closed connection\n");
			exit(0);
			}
		if (c == 13)
			continue;
		if (c == 10)
			break;
		s[la++] = c;
		}
	s[la] = 0;
	if (atoi(s) > 800)	{
		printf("mtalk: [%s]\n",s);
		exit(1);
		}
	return (la);
}
		
gl_tcp_open(host, service,port)
char *host;
char *service;
int port;
{
	struct in_addr adress;
	unsigned long ip_addr;
	int len;
	int fd, resvport;
	unsigned long inaddr;
	struct servent *sp;
	struct hostent *hp;

	bzero(( char *) &tcp_srv_addr, sizeof(tcp_srv_addr));
	tcp_srv_addr.sin_family = AF_INET;

	if (service != NULL)	{
		if (( sp = getservbyname(service,"tcp")) == NULL)	{
			return (-1);
			}
		tcp_serv_info = *sp;
		if (port > 0)
			tcp_srv_addr.sin_port = htons(port);
		else
			tcp_srv_addr.sin_port = sp->s_port;
		} 
	else	{
		if (port <= 0)	{
			great_errno = 101;
			return (-2);
			}
		tcp_srv_addr.sin_port = htons(port);
		}

	if ((inaddr = inet_addr(host)) != INADDR_NONE)	{
		bcopy((char *) &inaddr, (char *) &tcp_srv_addr.sin_addr,
			sizeof(inaddr));
		bcopy((char *) &inaddr, (char *) &adress.s_addr,
			sizeof(inaddr));
		tcp_host_info.h_name = NULL;
		}
	else	{
		if (( hp = gethostbyname(host)) == NULL)	{
			great_errno = 102;
			return (-3);	
			}
		tcp_host_info = *hp;
		bcopy(hp->h_addr, (char *) &tcp_srv_addr.sin_addr,
			hp->h_length);
		bcopy(hp->h_addr, (char *) &adress.s_addr,
			hp->h_length);
		}


        strcpy(current_ip,inet_ntoa(adress));

	if (port >= 0)	{
		if ((fd = socket(AF_INET, SOCK_STREAM,0)) < 0)	{
			great_errno = 108;
			return (-4);
			}
		}
	else if (port < 0)	{
		resvport = IPPORT_RESERVED -1;
		if (( fd = rresvport(&resvport) < 0))	{
			great_errno = 108;
			return (-5);
			}
		}
	alarm(60);
	if (connect(fd, (struct sockaddr *) &tcp_srv_addr,
		sizeof(tcp_srv_addr)) < 0)	{
		close(fd);
		great_errno = 107;
		alarm(0);
		return (-6);
		}

	len = sizeof (myctladdr);
	if (getsockname(fd, (struct sockaddr *)&myctladdr, &len) < 0) {
		perror("ftp: getsockname");
		alarm(0);
		close(fd);
		return(-7);
		}
	alarm(0);
	return (fd);
}


slow_write(int hd,char *s,int sz)
{
        int pos;
        int a;
        int written = 0;
        int tz;
        
        pos = 0;
        tz = sz;  


        while (1)       {
                a = write(hd,&s[pos],tz);
                if (a < 0)	
                        return (-1);
                pos +=a;
                tz -= a;
#ifdef DEBUG
                printf("slow_write: written <%d> towrite <%d>\n",pos,tz);
#endif
                if (pos >= sz)
                        return (pos);
                }

}

dhelp()
{
	printf("mtalk: Voice conversation via network\n");
	printf("(c) 1994 Free Software Association of Germany\n");
	printf("\nUsage: mtalk [-8] [-d] [-term] [-last] [hostname]\n");
	printf("-d      Produce some debugging info\n");
	printf("-8      Don't use GSM encoding - send plain data\n");
	printf("-term   Use port 5102 (tredir for use with term)\n");
	printf("-last   Connect to the currently calling host\n");
	printf("\n\nGSM en/decoding Copyright 1992 by Jutta Degener\n");
	printf("and Carsten Bormann, Technische Universitaet Berlin.\n");
	exit(0);
}

