#include <exec/types.h>
#include <devices/serial.h>
#include <libraries/dos.h>

/*******************************************************/
/* Programm nimmt Voice-Daten von der Telefonleitung   */
/* auf und spielt sie dann sofort auf modem-eigenen    */
/* Lautsprecher wieder ab. Dann werden die Voice-Daten */
/* im File 'ram:voice' abgelegt.                       */
/*******************************************************/


struct IOExtSer *SerRequest;
struct MsgPort *MsgPort;
BPTR handle, fh;
char Data, buf[2048], *VBuf;

/**-----------------------------------------------------------**/
/**  von ser. Schnittstelle lesen (in buf) bis LF (=10) kommt **/
/**-----------------------------------------------------------**/
long VRead()
{
int i, n;

   SerRequest->IOSer.io_Data = (APTR)&Data;
   SerRequest->IOSer.io_Length = 1;
   SerRequest->IOSer.io_Command = CMD_READ;

   i = 0;
   do {
      DoIO(SerRequest);
      buf[i++] = Data;
   } while (Data != 10 && i != 2047);
   if (i == 2047) printf("\nBuffer-Überlauf\n");
   buf[i] = 0; n = i;
   printf("\nString: %s", buf);
   return(n);
}

/**-----------------------------------------------------**/
/** Schreibt 'buf' zur ser. Schnittstelle bis Null-Byte **/
/**-----------------------------------------------------**/
void VWrite(buf)
char *buf;
{
int len=0;

   while(buf[len] != 0) len++;

   SerRequest->IOSer.io_Data = (APTR)buf;
   SerRequest->IOSer.io_Length = len;
   SerRequest->IOSer.io_Command = CMD_WRITE;
   DoIO(SerRequest);
}

char ETX[] = {16, 3, 13};

main()
{
int n, len=0;
register int i;
register char rc;
register BOOL dle_Flag;

   handle = Output();
   if ((MsgPort = (struct MsgPort *)CreatePort(NULL, 0L)) == 0)
   {
      printf("kein Port\n");
      exit(0);
   }
   if ((SerRequest = (struct IOExtSer *)CreateExtIO(MsgPort,
                             sizeof(struct IOExtSer))) == 0)
   {
      printf("Kein Request\n");
      goto Port;
   }

   SerRequest->io_Baud = 19200;
   SerRequest->io_ReadLen = SerRequest->io_WriteLen = 8;
   SerRequest->io_StopBits = 1;
   SerRequest->io_SerFlags = SERF_7WIRE|SERF_SHARED;
   SerRequest->io_ExtFlags = 0;

   if (OpenDevice("serial.device", 0L, SerRequest, 0L))
   {
      printf("kein Device\n");
      goto Request;
   }

   if ((VBuf = (char *)AllocMem(100*1024, 0)) == 0)
   {
      printf("kein Speicher !\n");
      goto End;
   }


/**  Auf Voice-Modus schalten  **/

   VWrite("AT+FCLASS=8\r");
   printf("Init geschrieben\n");

   do {
      n = VRead();
   } while(buf[0] != 'O' && buf[1] != 'K');
   /*  Liest bis 'OK' kommt  */


/* Schaltet CELP (VSM=1) ein und die Ausgabe auf Telefonleitung (VLS=2)
/* Nicht-Plus-Besitzer sollten hier ADPCM2 (VSM=2) oder ADPCM3 (=3) wählen
/* Dann aber sollte die Übertragungsrate auf 38400 oder höher gestellt
/* werden. Das gibt aber Probleme bei einer 68000 CPU. */

   VWrite("AT+VSM=1+VLS=2\r");

   n = VRead();
   n = VRead();
/****************   Hier kann man jemanden anwählen,
                    wie hier z.B. die Telefonansage.
Ist der Teil in Kommentar gesetzt (wie jetzt), so wird das Freizeichen
aufgenommen (ist billiger :)

   VWrite("ATDP01191\r");

   do {
      n = VRead();
   } while(buf[0] != 'N' && buf[0] != 'V');
         /* bis Antwort 'NO ANSWER' oder 'VCON'
   if (buf[0] == 'N') goto terminate;  /* bei 'NO ANSWER' Abbruch
****************************/

/* auf Aufnahme schalten */
   VWrite("AT+VRX\r");

   n = VRead();
   n = VRead();

   printf("Lese nun Voice-Daten\n");

   SerRequest->IOSer.io_Data = (APTR)VBuf;
   SerRequest->IOSer.io_Length = i = 16*1024;
   SerRequest->IOSer.io_Command = CMD_READ;
   DoIO(SerRequest);             /*   Lese Voice-Daten  */
   printf("fertig gelesen\n");

   VWrite("AT\r");   /* Abbruch */

   do {
      SerRequest->IOSer.io_Data = (APTR)&Data;
      SerRequest->IOSer.io_Length = 1;
      SerRequest->IOSer.io_Command = CMD_READ;
   /*  Lese nun restliche Daten  */

      do {
         DoIO(SerRequest);
         VBuf[i++] = Data;
      } while (Data != 10 && i != 100*1024);
      if (i == 100*1024) printf("\nBuffer-Überlauf\n");
      VBuf[i] = 0; n = i;
   } while(VBuf[n-2] != 13 || VBuf[n-3] != 'N' || VBuf[n-4] != 'O');
  /*  Solange bis String 'VCON' kommt  */

   printf("String: %sLänge Daten: %d\n", &VBuf[n-6], len=n);


/* CELP einschalten und Ausgabe auf eingebauten Lautsprecher */

   VWrite("AT+VSM=1+VLS=16\r");

   n = VRead();
   n = VRead();


/* auf Wiedergabe schalten */

   VWrite("AT+VTX\r");

   n = VRead();
   n = VRead();

   printf("Schreibe nun Voice-Daten\n");

   SerRequest->IOSer.io_Data = (APTR)VBuf;
   SerRequest->IOSer.io_Length = len-7;
   SerRequest->IOSer.io_Command = CMD_WRITE;
   DoIO(SerRequest);               /* Schreibe Voice-Daten */
   printf("fertig geschrieben\n");

   n = VRead();
   n = VRead();

terminate:
   printf("schreibe Rückkehr-Kommando\n");
   VWrite("AT+VLS=0+FCLASS=0\r", 18);

   n = VRead();
   n = VRead();

/*  Status Schnittstelle holen  */
   SerRequest->IOSer.io_Command = SDCMD_QUERY;
   DoIO(SerRequest);
   printf("Status : %x\n", SerRequest->io_Status);

/* Schreibe Daten in ein File
   (kann mit Prog. 'vp' wieder abgespielt werden) */
   if (len>7)
   if ((fh = Open("ram:voice", MODE_NEWFILE)) != 0)
   {
      Write(fh, VBuf, len-7);
      Close(fh);
   }
   else
      printf("Voicefile läßt sich nicht öffnen\n");

   FreeMem(VBuf, 100*1024);
End:
   CloseDevice(SerRequest);
Request:
   DeleteExtIO(SerRequest);
Port:
   DeletePort(MsgPort);
   exit(0);
}
