
/* 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 <stdio.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <sys/stat.h>
#include <errno.h>
#include "gsm.h"
#include "ulaw.h"


#define PIPE "/tmp/mtalkpipe"

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

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

char username[200];
int MODE = 0;

char FNAME[512];
char NOTALK[512];

bye()
{
/*	unlink(PIPE); */
	exit(1);
} 

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

	while (read(0,&c,1) == 1)	{
		if (c == 10)
			break;
		s[la++] = c;
		} 
	s[la] = 0;
	return (la);
 }

main(int argc, char **argv)
{
	FILE *fp;
	char s[1024];
	char sp[1024];
	int hd;
	struct stat stb;
	unsigned char *p;
	int a,b,size;


	setbuf(stdout,NULL);

	strcpy(username,"unknown");

	strcpy(FNAME,"/tmp/mtalk.user");
	strcpy(NOTALK,"/tmp/mtalk.no");
	
	get_peerip(sp);

	fp = fopen(FNAME,"w");
	fprintf(fp,"%s\n",sp);
	fclose(fp);


	if (!stat(NOTALK,&stb))	{
		printf("901 Sorry - Phone is currently offline\r\n");
		exit(1);
		}

	printf("100 MTALK 0.5 (from %s) ready\r\n",sp);

	while (1)	{
		read_line(s);
		if (atoi(s) == 0)	{
			printf("MTALK server closing connection\r\n");
			bye();
			}
		if (atoi(s) == 2)	{
			MODE  = atoi(&s[4]);
			printf("100 Mode %d\r\n",MODE);
			}
		if (atoi(s) == 3)	{
			size = atoi(&s[4]);
			p = (unsigned char *)malloc(size);
			if (p == NULL)	{
				printf("901 Unable to malloc %d bytes\r\n");
				bye();
				}
			printf("102 r %d\r\n",size);
			a = slow_read(0,p,size);
			printf("102 g %d\r\n",a);
			decode_voice(p,a);
			exit(0);
			}

		}
} 


decode_voice(unsigned char *p, int size)
{
	gsm handle;
	gsm_frame buf;
	gsm_signal sample[160];
	int hd;
	int aa,a,b;
	unsigned char c;

	for (a = 0; a < 10; a++)	{
		hd = open("/dev/audio",O_WRONLY);
		if (hd < 0)	{
			sleep(1);
			continue;
			}
		break;
		}

	if (hd <= 0)	{
		printf("901 Unable to open /dev/audio (%s)\r\n",sys_errlist[errno]);
		return (-1);
		}

	if (MODE  == 1)	{
		if (!(handle = gsm_create()))  { 
			printf("901 Unable to create gsm handle\r\n");
			bye();
			}
		}

	if (MODE == 0)	{  /* Plain sun au format */
		for (a = 0; a < size; a++)
			write(hd,&p[a],1);
		} 

	if (MODE == 1)	{ /* GSM encoded sun au format */
		for (a = 0; a < size; a++)	{
			buf[b++] = p[a];
			if (b == sizeof(buf))	{
				b = 0;
				if (gsm_decode(handle, buf, sample) < 0)
					continue;
				for (aa = 0; aa < 160; aa++)       {
		                        c = S2U(sample[aa]);
		                        write(hd,&c,1);
		                        }
				}
			} 
		}

	close(hd);
	if (MODE == 1)
		gsm_destroy(handle);

	return (0);
}




get_peerip(char *s)
{
	struct in_addr adress;
	struct sockaddr_in      cli_addr;
        struct hostent  *hp;
        unsigned long ip_addr;
        int     hd,ch, addrlen;

	addrlen = sizeof(cli_addr);
	if (getpeername(0, &cli_addr, &addrlen) < 0)    {
		strcpy(s,"0.0.0.0");
               	return(1);
                }
        adress.s_addr = cli_addr.sin_addr.s_addr;
        strcpy(s,inet_ntoa(adress));
	return(0);
}


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


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

