/***************************************************************************
                         gesko.c     -  description
                             -------------------
    Program for GESKO-PBX with 19200 BAUD e.g. Office1106/2108

    begin                : Wed Dec  8 16:41:45 MET 1999

    copyright            : (C) 1999 by Thomas Marquardt
    email                : th.marquardt@t-online.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <math.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <ctype.h>

#include "gesko.h"


#define MAX_ANZ_DATEN 2000
#define BlockLen      100

char			pv[32];
struct		einr_daten	pe;

extern int fw_dld;

/*****************************************************************************/
/* Funktion zur Berechnung der Checksumme                                    */
/* --------------------------------------                                    */
/* In:	s - Pointer auf Zeichenkette,                                        */
/*      i - halbe Laenge der Zeichenkette                                    */
/* --------------------------------------                                    */
/* Out:	csum - die Checksumme als Integer                                    */
/* --------------------------------------                                    */
/* Autor: Bodo Rzany                                                         */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
int csum( unsigned char *s, int i )
{
   unsigned int c = 0;
   char h[] = "\0\0\0\0";
   

   for ( ; i; i-- )
   {
      if ( c & 01 )  c = ( c >> 1 ) | 0x8000 ;
      else           c = ( c >> 1 ) & 0x7fff ;
      *(h+0) = *(s+1);
      *(h+1) = *(s+0);
      c += (int) strtoul(h,NULL,16);
      s+=2;
   }
   return c;
}


/*****************************************************************************/
/* Diese Funktion wandelt einen Char in einen Byte-Wert um                   */
/* -------------------------------------------------------                   */
/* In:	c - zu wandelnder character                                          */
/* --------------------------------------                                    */
/* Out:	Xfer - der entsprechende Wert                                        */
/* --------------------------------------                                    */
/* Autor: Thomas Marquardt                                                   */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
byte HexCharToByte (unsigned char c )
{
  byte Xfer = 0;


  switch ( c )
  {
    case '0': case '1':case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
      Xfer = c - 48;
    break;
    case 'A': case 'B':case 'C': case 'D': case 'E': case 'F':
      Xfer = c - 55;
    break;
    case 'a': case 'b':case 'c': case 'd': case 'e': case 'f':
      Xfer = c - 87;
    break;
    default:
      Xfer = 0x00;
    break;
  }
  return ( Xfer );
}


/*****************************************************************************/
/* Diese Funktion wandelt einen String mit einer Hexzahl in einen Wert um    */
/* ----------------------------------------------------------------------    */
/* In:	HexString - Pointer auf den String                                   */
/* ----------------------------------------                                  */
/* Out:	Summe - Der Wert der dem HexString entspricht                        */
/* ---------------------------------------------------                       */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
long HexToWert( unsigned char * HexString )
{
   int    Laenge,
          stelle;

   float  Basis,
          Exponent,
          Neu;

   byte   Wert;

   long   Summe;


   Laenge = strlen (HexString);
   Summe = 0;
   for (stelle = 0; stelle < Laenge; stelle++)
   {
     Wert = HexCharToByte ( HexString[stelle]);
     Basis = 16;
     Exponent = Laenge - stelle - 1;
     Neu = Wert * pow(Basis, Exponent);
     Summe = Summe + (long)(Neu + 0.5);
   }
   return ( Summe );
}



/*****************************************************************************/
/* Diese Funktion wandelt einen Wert in einen Char um der dem Hexsystem      */
/* entspricht.                                                               */
/* --------------------------------------------------------------------      */
/* In:	b - der Wert                                                         */
/* ------------------                                                        */
/* Out:	Xfer - Das dem Wert entsprechende Zeichen (z.B. fuer Wert 10 -> A    */
/* -----------------------------------------------------------------------   */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
unsigned char ByteToHexChar ( byte b )
{
  char Xfer;


  if ( b <= 9 )                /* 0 - 9 */
    Xfer = (unsigned char)(b + 48);
  else                         /* A - F */
    Xfer = (unsigned char)(b + 55);

  return ( Xfer );
}


/*****************************************************************************/
/* Diese Funktion wandelt einen Wert in einen String um der dem Hexsystem    */
/* entspricht                                                                */
/* ----------------------------------------------------------------------    */
/* In:	Wert - der umzuwandelnde Wert                                        */
/* ------------------------------------                                      */
/* Out:	buf - Pointer auf den String, in dem der Hexwert steht               */
/* ------------------------------------------------------------              */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
unsigned char * WertToHex ( long Wert )
{
  unsigned char *buf=malloc(0x20);

  sprintf (buf, "%lx", Wert);
  return ( buf );
}


/*****************************************************************************/
/* Mit dieser Funktion wird die Checksumme eines Strings von der TK-Anlage   */
/* mit der selbst berechneten Checksumme verglichen                          */
/* ----------------------------------------------------------------------    */
/* In:	InString - Pointer auf den eingelesenen String                       */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR bei gleicher Checksumme sonst ERROR                         */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
int TestChecksumme (unsigned char * InString)
{
  unsigned char  ChecksummePc[0x10],
                 ChecksummePbx[0x10];
  int   len,
        Csum,
        ret = ERROR;


  len = strlen(InString);
  
  if ( len )
  {
    strncpy (ChecksummePbx, &InString[0], 4);
  
    InString += 4;
    len  -= 4;
    Csum = csum (InString, len/2);
    sprintf ( ChecksummePc, "%01X%01X%01X%01X", 
			  Csum & 0xf, (Csum >> 4) & 0xf, (Csum >> 8) & 0xf, (Csum >> 12) & 0xf );

    if ( strncmp(ChecksummePbx, ChecksummePc, 4) != 0 )
    {
        printf ("Checksum failed\n");
        printf ("InString=%s  PC=%4s  PBX=%4s\n", InString, ChecksummePc, ChecksummePbx);
        ret = ERROR;
    }
    else
      ret = NO_ERROR;
  }

  return (ret);
}


/*****************************************************************************/
/* Mit dieser Funktion wird ein String von der TK-Anlage konvertiert. Zuerst */
/* einmal wird immer pro Bytepaar eine Drehung ausgeführt, dann werden aus   */
/* dem String Checksumme, BufferNo, BufferAnz usw. rausgeschnitten. Übrig    */
/* bleibt ein String, der je nach Befehl aus Daten oder ASCII-Zeichen besteht*/
/* ----------------------------------------------------------------------    */
/* In:	InString - Pointer auf den eingelesenen String                       */
/* ---------------------------------------------------                       */
/* Out:	OutString - Pointer auf den modifizierten String                     */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
void ZerlegeString ( unsigned char * InString, unsigned char * OutString )
{
  int  Laenge,
       DatenLaenge,
       i, Position;

  unsigned char DatenLen[0x10];

  unsigned char FirstChar,
                LastChar;


  Laenge = strlen(InString);
  i = 0;
  while ( i < Laenge )
  {
    Position  = i+1;
    FirstChar = InString[i];
    LastChar  = InString[i+1];
      InString[i] = LastChar;
    InString[i+1] = FirstChar;
    i += 2;
  }
  
  strncpy (DatenLen, &InString[14], 2);
  DatenLen[2] = '\0';
  DatenLaenge = HexToWert( DatenLen );
  strncpy (OutString, &InString[16], (DatenLaenge * 2) + 1);
  #ifdef MARQ_TEST
    printf ("ZerlegeString\n");
  #endif
}


/*****************************************************************************/
/* Mit dieser Funktion wird ein DatenString von der TK-Anlage in Binärdaten  */
/* konvertiert.                                                              */
/* ----------------------------------------------------------------------    */
/* In:	InString - Pointer auf den eingelesenen String                       */
/* ---------------------------------------------------                       */
/* Out:	OutString - Pointer auf den modifizierten String                     */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
int ChangeStringToBinary ( unsigned char * InString, unsigned char * OutString )
{
  int  len = 0,
       i = 0;
  unsigned char ValStr[0x10];

  ValStr[2] = '\0';
  while ( i < strlen(InString) )
  {
	  memcpy (ValStr, InString+i, 2);
    i += 2;
    OutString[len++] = HexToWert ( ValStr );
  }

  return ( len );
}



/*****************************************************************************/
/* Mit dieser Funktion wird eine Konvertierung von Daten in ASCII-Zeichen    */
/* ausgeführt. Das macht natürlich nur Sinn, wenn im Befehl eine Antwort in  */
/* ASCII angefordert wurde.                                                  */
/* ----------------------------------------------------------------------    */
/* In:	InString - Pointer auf den Datenstring                               */
/* ---------------------------------------------------                       */
/* Out:	OutString - Pointer auf den modifizierten String                     */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
void TranslateString ( unsigned char *InString, unsigned char * OutString)
{
  int  Laenge,
       i, j;
  
  byte Wert;
 
  unsigned char TeilString[0x10];


  Laenge = strlen( InString );
  strcpy (OutString, "");
  if ( Laenge > 0 )
  {
    i = 0;
    j = 0;
    while ( i < Laenge )
    {
      strcpy (TeilString, "");
      strncpy (TeilString, &InString[i], 2);
      TeilString[2] = '\0';
      Wert = HexToWert ( TeilString );
      OutString[j++] = (unsigned char)Wert;
      OutString[j] = '\0';
      i += 2;
    }
  }
  #ifdef MARQ_TEST
    printf ("TranslateString\n");
  #endif
}


/*****************************************************************************/
/* Diese Funktion bastelt es der Struktur Cmd den Ausgabe-String.            */
/* ----------------------------------------------------------------------    */
/* In:	argc - Argumentencounter                                             */
/*      argv - Pointer auf die Argumentenvektoren                            */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                */
/* ----------------------------------------------------                      */
/* Autor: Bodo Rzany / Th. Marquardt                                         */
/* letzte Aenderung: Th. Marquardt 07.12.99                                  */
/*****************************************************************************/
   /*          10        20        30        40        50         60 */
   /* 0123456789012345678901234567890123456789012345678901234567890  */
   /*  cccc1000100000llbbbbbbbb111111112222222233333333llllddddddddddddd>*/
   /*  Chk Header    len                                             */
   /*                  Befehl                                        */
   /*                      Para1   Para2   Para3   len daten         */
   /* Startzeichen      Stelle= 0  Laenge= 1                         */
   /* Checksumme        Stelle= 1  Laenge= 4                         */
   /* Header            Stelle= 5  Laenge=10                         */
   /* len               Stelle=15  Laenge= 2                         */
   /* Befehl            Stelle=17  Laenge= 8                         */
   /* Parameter 1       Stelle=25  Laenge= 8                         */
   /* Parameter 2       Stelle=33  Laenge= 8                         */
   /* Parameter 3       Stelle=41  Laenge= 8                         */
   /* len               Stelle=49  Laenge= 4                         */
   /* daten             Stelle=53  Laenge= variabel                  */

int MakeOutString ( cmdtype Cmd, unsigned char * buf )
{
   int slen, dlen, i, j, end;
   unsigned char xx[16];


   /* printf ("Befehl=%s  %ld  %ld  %ld \n", Cmd.befehl, Cmd.param[0], Cmd.param[1], Cmd.param[2]);   */
   slen= strlen(Cmd.befehl);

   /* Startzeichen Binaer 2 und Platzhalter fuer Checksumme und Header */
   sprintf( buf, "\00200001000100000");

   /* Befehl */
   for ( i=0 ; i < slen ; i++ )
   {
     sprintf( buf+17+(2*i), "%01X%01X", *(Cmd.befehl+i)&0xf, *(Cmd.befehl+i)>>4 );
   }

   /* Anzahl der Parameter ermitteln */
   if ( Cmd.param_anz <= 3 )
     end = Cmd.param_anz;
   else
     end = 3;

   /* Parameter 1 bis 3 */
   for ( j = 0; j < end; j++ )
   {
     sprintf( xx, "%08lX", Cmd.param[j] & 0xffffffff );
     for (i = 0; i < 8 ; i++)
       *(buf + 17 + (2 * slen) + i) = *(xx + 7 - i);
     slen += 4;
   }

   if (Cmd.param_anz > 3)
   {
     /* Daten */
     dlen = 0;
     for (i = 0; i < Cmd.data_len; i+=2)
     {
       *(buf + 53 + i + 1) = Cmd.daten[i];
       *(buf + 53 + i)     = Cmd.daten[i+1];
       slen++;
       dlen++;
     }
     /* Laengenangabe fuer die Daten */
     sprintf( xx, "%01x%01x00", dlen & 0xf, dlen >> 4 );
     strncpy( buf + 49, xx, 4);
     slen+=2;
   }

   /* Laengenangabe ueber alles */
   sprintf( xx, "%01x%01x", slen & 0xf, slen >> 4 );
   strncpy( buf + 15, xx, 2);
   /* printf ("Len=%2s  %d\n", xx, slen); */

   /* CR + NL anhängen */
   sprintf( buf + 17 + (2 * slen), "\r\n" );

   /* Checksumme bestimmen */
   i = csum( buf + 5, slen + 6 );
   sprintf ( xx, "%01X%01X%01X%01X", i & 0xf, (i >> 4) & 0xf, (i >> 8) & 0xf, (i >> 12) & 0xf );
   strncpy(buf + 1, xx, 4);
   #ifdef MARQ_TEST
     printf ("MakeOutString\n");
   #endif
   return ( (2 * slen) + 19 );
}



/*****************************************************************************/
/* Funktion fuer die UEbertragung von Daten im Konfigurations-Format.        */
/* ----------------------------------------------------------------------    */
/* In:	argc - Argumentencounter                                             */
/*      argv - Pointer auf die Argumentenvektoren                            */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                */
/* ----------------------------------------------------                      */
/* Autor: Bodo Rzany / Th. Marquardt                                         */
/* letzte Aenderung: Steffen Hildebrandt 10.01.2003                          */
/*****************************************************************************/
int ConfPbxPutAndGet ( cmdtype Cmd, unsigned char * daten, unsigned char * text, int Anzeige )
{
   int slen, i;
   unsigned char *outbufraw  = malloc(512);
   unsigned char *inbufraw   = malloc(512);
   int ret = ERROR;		
	 int erg_out = NO_ERROR;
	 int erg_in = NO_ERROR;


   /* Einen Command-String in 'buf' zusammenstellen	*/
   slen = MakeOutString ( Cmd, outbufraw );
   
   i = 3;
   do
   {
     erg_out = SerialOut (outbufraw, slen );
   	 erg_in = SerialIn ( inbufraw, (char)10 );  
     if ( *inbufraw == 0x02 )                            /* delete stx */
	    inbufraw++;
     slen = strlen ( inbufraw );
     ret = TestChecksumme (inbufraw);
   }     
   while ( ret == ERROR && i-- && slen > 4 );
   if ( ret == ERROR )
   {
	    printf ("\n\nFEHLER: Fehler bei Uebertragung eines CONF-Befehls! -> ABBRUCH!\n\n");
      if ( fw_dld == TRUE )
				printf("HINWEIS : Vor neuem Firmware-Download die Anlage per Netztstecker resetten!\n\n");
	    exit(0);
   }
   ZerlegeString (inbufraw, daten);
   TranslateString (daten, text);

   if ( Anzeige )
   {
			printf ("\nCONF Output    : %s  ", Cmd.befehl);
			for (i = 0; i < Cmd.param_anz; i++)
					printf ("%ld  ", Cmd.param[i]);
			if ( Cmd.param_anz > 3 )
			printf ("%s", Cmd.daten);
			printf ("\n");
			/* printf ("                          10        20        30        40        50\n"); */
			/* printf ("                 012345678901234567890123456789012345678901234567890123456789\n"); */
			printf ("Transmit Raw   : %s", outbufraw);
			printf ("Response Raw   : len=%3d : %s\n", slen, inbufraw);
			printf ("Response Data  : len=%3d : %s\n", strlen(daten), daten);
			printf ("Response Ascii : len=%3d : %s\n", strlen(text), text);
   }
   
	 if ( erg_out == ERROR || erg_in == ERROR )
      return ERROR;
	  else	 		
   		return NO_ERROR;
}
     
/*****************************************************************************/
/* Funktion fuer die Uebertragung von Daten im GT-Format.                    */
/* ----------------------------------------------------------------------    */
/* In:	argc - Argumentencounter                                             */
/*      argv - Pointer auf die Argumentenvektoren                            */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Steffen Hildebrandt 10.01.2003                          */
/*****************************************************************************/
int GTPbxPutAndGet ( cmdtype Cmd, unsigned char *antwort, int Anzeige )
{
	 short j;
   int slen;
   int ret = ERROR;		
	 int erg_out = NO_ERROR;
	 int erg_in = NO_ERROR;


   strcat (Cmd.befehl, "\r\n");         /* <CR> + <LF> anhaengen */

	 j = MAX_TRYS;
   do
   {
		 erg_out = SerialOut (Cmd.befehl, strlen (Cmd.befehl) );
     erg_in = SerialIn ( antwort, (char)10 );
     slen = strlen ( antwort );
	   if ( slen )
	     ret = NO_ERROR;
   }
   while ( ret == ERROR && --j != 0);

   if ( ret == ERROR )
   {
	    printf ("\n\nFEHLER: Fehler bei Uebertragung eines GT-Befehls! -> ABBRUCH!\n\n");
      if ( fw_dld == TRUE )
				printf("HINWEIS : Vor neuem Firmware-Download die Anlage per Netztstecker resetten!\n\n");
	    exit(0);
   }

	 if ( Anzeige )
	 {	 
     printf ("\nGT Command : Len=%3d : %s\n", strlen (Cmd.befehl), Cmd.befehl);
     printf ("Response   : Len=%3d : %s\n", slen, antwort);
     printf ("\n");
   }

	 if ( erg_out == ERROR || erg_in == ERROR )
      return ERROR;
	  else	 		
   		return ret;
}


/*******************************************************************************/
/* Funktion fuer die Uebertragung der Gespraechsdaten mit Konfigurationsformat */
/* ----------------------------------------------------------------------      */
/* In:	void                                                                   */
/* ---------------------------------------------------                         */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                  */
/* ----------------------------------------------------                        */
/* Autor: Th. Marquardt                                                        */
/* letzte Aenderung: Steffen Hildebrandt, 09.04.2003                           */
/*******************************************************************************/
int GespConfPbxPutAndGet ( int mode )
{
   int i;
   unsigned char *daten = malloc(512);
   unsigned char *text  = malloc(512);
   int ret = ERROR;		
   cmdtype Cmd;
	 FILE *gsp_fd = NULL;
	 unsigned char *temp_string = calloc(128, 1);   


   if(mode == GSPDATA_NEW)
     gsp_fd = fopen("./gspdata.txt", "w+");
   if(mode == GSPDATA_APPEND)
     gsp_fd = fopen("./gspdata.txt", "a");

	 if(gsp_fd == NULL)
	 {
	    printf("FEHLER : File fuer Gespraechsdaten <gspdata.txt> konnte nicht geoeffnet werden!\n");
		  return ERROR;
	 }

	 printf("\nHINWEIS : Gespaechsdaten werden in das File <gspdata.txt> geschrieben!\n\n");

   strcpy (Cmd.befehl, "I209");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "OK", 2) != 0)
   {
	   printf ("ERROR!\n");
     exit (0);
   }
   printf (" No.   Date     Dir  Subsc            calling-number  time   duration units value S0 MSN\n");
	 fputs(" No.   Date     Dir  Subsc            calling-number  time   duration units value S0 MSN\n", gsp_fd);
   printf ("----------------------------------------------------------------------------------------\n");
   fputs("----------------------------------------------------------------------------------------\n", gsp_fd);
	 fflush(gsp_fd);

   strcpy (Cmd.befehl, "GESP");
   Cmd.param_anz = 1;
   i = 0;
   while ( (strncmp(text, "BYE", 3) != 0) && (i < MAX_ANZ_DATEN) )
   {
     if ( i++ == 0 )
       Cmd.param[0] = 3;
     else
       Cmd.param[0] = 4;
     ConfPbxPutAndGet (Cmd, daten, text, 0);
     if (strncmp(text, "BYE", 3) != 0)
		 {
       printf ("%4d  ", i);
	     sprintf(temp_string, "%4d  ", i);
       fputs(temp_string, gsp_fd);
       ShowGespDat ( daten, gsp_fd );
		 }
   }

   printf ("\n%d actions\n", i - 1);
	 sprintf(temp_string, "\n%d actions\n", i - 1); 
	 fputs(temp_string, gsp_fd);

	 fflush(gsp_fd);
	 fclose(gsp_fd);

   ret = NO_ERROR;
   return (ret);
}


/*****************************************************************************/
/* Funktion fuer die Uebertragung der Gespraechsdaten mit GT-Format          */
/* ----------------------------------------------------------------------    */
/* In:	void                                                                 */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Steffen Hildebrandt, 09.04.2003                         */
/*****************************************************************************/
int GespGtPbxPutAndGet ( int mode )
{
   int i;
   unsigned char *antwort  = malloc(512);
   int ret = ERROR;		
   cmdtype Cmd;
	 FILE *gsp_fd = NULL;
	 unsigned char *temp_string = calloc(128, 1);   


   if(mode == GSPDATA_NEW)
     gsp_fd = fopen("./gspdata.txt", "w+");
   if(mode == GSPDATA_APPEND)
     gsp_fd = fopen("./gspdata.txt", "a");

	 if(gsp_fd == NULL)
	 {
	    printf("FEHLER : File fuer Gespraechsdaten <gspdata.txt> konnte nicht geoeffnet werden!\n");
		  return ERROR;
	 }

	 printf("\nHINWEIS : Gespaechsdaten werden in das File <gspdata.txt> geschrieben!\n\n");

   printf (" No.   Date     Dir  Subsc            calling-number  time   duration units value S0 MSN\n");
	 fputs(" No.   Date     Dir  Subsc            calling-number  time   duration units value S0 MSN\n", gsp_fd);
   printf ("----------------------------------------------------------------------------------------\n");
   fputs("----------------------------------------------------------------------------------------\n", gsp_fd);
   i = 0;
   while ( (strncmp(antwort, "BYE", 3) != 0) && (i < MAX_ANZ_DATEN) )
   {
     if ( i++ == 0 )
       strcpy (Cmd.befehl, "GTG3");
     else
       strcpy (Cmd.befehl, "GTG4");
     GTPbxPutAndGet (Cmd, antwort, 0);  
     if (strncmp(antwort, "BYE", 3) != 0)
     {
       if (strncmp(antwort, "ERROR", 5) != 0)
			 {
         //printf ("%s\n", antwort);
         printf ("%4d  ", i);
			   sprintf(temp_string, "%4d  ", i);
         fputs(temp_string, gsp_fd);
         ShowGespDat ( antwort, gsp_fd );
			 }
     }
   }

   printf ("\n%d actions\n", i - 1);
	 sprintf(temp_string, "\n%d actions\n", i - 1); 
	 fputs(temp_string, gsp_fd);

	 fflush(gsp_fd);
	 fclose(gsp_fd);

   ret = NO_ERROR;
   return (ret);
}


/*****************************************************************************/
/* Funktion für die lesende Übertragung des Einrichtdatenblocks              */
/* ----------------------------------------------------------------------    */
/* In:	void                                                                 */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 17.11.2000                                */
/*****************************************************************************/
int GetL7EinrBlock ( EINRICHT_BLOCK L7_Einr_Block )
{
   int BinLen;
   int i, ReadLen = 0;
   int GesamtLen = sizeof (L7_Einr_Block);
   int Grenze;
   int BytePtr;
   unsigned char *daten = malloc(512);
   unsigned char *text  = malloc(512);
   unsigned char *root;
   unsigned char *PtrBisKwz = (void *)&L7_Einr_Block.kwz;
   unsigned char *PtrNachKwz = (void *)&L7_Einr_Block.hotline;
   int ret = ERROR;	
   cmdtype Cmd;	


   printf ("\nLese L7_Einr_Block Groesse=%d\n", GesamtLen);
   
   memset (&L7_Einr_Block, 0x00, sizeof (L7_Einr_Block));
   memset (&Cmd, 0x00, sizeof (cmdtype));
   
   strcpy (Cmd.befehl, "I209");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "OK", 2) != 0)
     return (ret);

   /* Block holen bis zum Beginn der Kurzwahlziele */
   strcpy (Cmd.befehl, "EINR");
   Cmd.param_anz = 3;
   Cmd.param[0] = 1;
   root = (void *)&L7_Einr_Block;
   Grenze = PtrBisKwz - root;
   BytePtr = 0;
   while ( BytePtr < Grenze )
   {
	 Cmd.param[1] = BytePtr;
     if ( (BytePtr + BlockLen) <= Grenze )
       Cmd.param[2] = BlockLen;
     else
       Cmd.param[2] = Grenze - BytePtr;
     i = 3;  
     do
     {  
       ConfPbxPutAndGet (Cmd, daten, text, 0);
       BinLen = ChangeStringToBinary (daten, text);
     }while ( BinLen != Cmd.param[2] && i-- );  
     if ( i == 0 )
       printf ("Error: BinLen=%d\n", BinLen);
     ReadLen += BinLen;
     memcpy ( root, text, BinLen );
     root += BinLen;
     BytePtr += Cmd.param[2];
     printf ("%4d Bytes\n", ReadLen);
   }
   
   /* Rest des Blocks nach den Kurzwahlzielen holen */
   root = (void *)&L7_Einr_Block;
   BytePtr = PtrNachKwz - root;
   root = PtrNachKwz;
   while ( BytePtr < GesamtLen )
   {
	 Cmd.param[1] = BytePtr;
     if ( (BytePtr + BlockLen) <= GesamtLen )
       Cmd.param[2] = BlockLen;
     else
       Cmd.param[2] = GesamtLen - BytePtr;
     i = 3;  
     do
     {  
       ConfPbxPutAndGet (Cmd, daten, text, 0);
       BinLen = ChangeStringToBinary (daten, text);
     }while ( BinLen != Cmd.param[2] && i-- );  
     if ( i == 0 )
       printf ("Error: BinLen=%d\n", BinLen);
     ReadLen += BinLen;
     memcpy ( root, text, BinLen );
     root += BinLen;
     BytePtr += Cmd.param[2];
     printf ("%4d Bytes\n", ReadLen);
   }
   
   strcpy (Cmd.befehl, "ENDE");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "BYE", 3) != 0)
     return (ret);

   MakeCfgFile ( L7_Einr_Block );
   ret = NO_ERROR;
   return (ret);
}


/*****************************************************************************/
/* Funktion für die lesende Übertragung des MSN-Blocks                       */
/* ----------------------------------------------------------------------    */
/* In:	void                                                                 */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 17.11.2000                                */
/*****************************************************************************/
int GetL7MsnBlock ( MSN_BLOCK L7_Msn_Block )
{
   int BinLen;
   int i, ReadLen = 0;
   int GesamtLen = sizeof (L7_Msn_Block);
   int BytePtr;
   unsigned char *daten = malloc(512);
   unsigned char *text  = malloc(512);
   unsigned char *root;
   int ret = ERROR;	
   cmdtype Cmd;	


   printf ("\nLese L7_Msn_Block Groesse=%d\n", GesamtLen);

   memset (&L7_Msn_Block, 0x00, sizeof (L7_Msn_Block));

   strcpy (Cmd.befehl, "I209");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "OK", 2) != 0)
     return (ret);

   strcpy (Cmd.befehl, "MSNK");
   Cmd.param_anz = 3;
   Cmd.param[0] = 1;
   root = (void *)&L7_Msn_Block;
   BytePtr = 0;
   while ( BytePtr < GesamtLen )
   {
	 Cmd.param[1] = BytePtr;
     if ( (BytePtr + BlockLen) <= GesamtLen )
       Cmd.param[2] = BlockLen;
     else
       Cmd.param[2] = GesamtLen - BytePtr;
     i = 3;  
     do
     {  
       ConfPbxPutAndGet (Cmd, daten, text, 0);
       BinLen = ChangeStringToBinary (daten, text);
     }while ( BinLen != Cmd.param[2] && i-- );  
     if ( i == 0 )
       printf ("Error: BinLen=%d\n", BinLen);
     ReadLen += BinLen;
     memcpy ( root, text, BinLen );
     root += BinLen;
     BytePtr += Cmd.param[2];
     printf ("%4d Bytes\n", ReadLen);
   }
   
   strcpy (Cmd.befehl, "ENDE");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "BYE", 3) != 0)
     return (ret);

   MakeMsnFile ( L7_Msn_Block );
   ret = NO_ERROR;
   return (ret);
}


/*****************************************************************************/
/* Funktion für die lesende Übertragung des TLN-Blocks                       */
/* ----------------------------------------------------------------------    */
/* In:	void                                                                 */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 17.11.2000                                */
/*****************************************************************************/
int GetL7TlnBlock ( TLN_BLOCK L7_Tln_Block )
{
   int BinLen = 0;
   int GesamtLen = sizeof (L7_Tln_Block);
   int BytePtr;
   int i, ReadLen = 0;
   unsigned char *daten = malloc(512);
   unsigned char *text  = malloc(512);
   unsigned char *root;
   int ret = ERROR;	
   cmdtype Cmd;	


   printf ("\nLese L7_Tln_Block Groesse=%d\n", GesamtLen);

   memset (&L7_Tln_Block, 0x00, sizeof (L7_Tln_Block));
   
   strcpy (Cmd.befehl, "I209");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "OK", 2) != 0)
     return (ret);

   strcpy (Cmd.befehl, "TLND");
   Cmd.param_anz = 3;
   Cmd.param[0] = 1;
   root = (void *)&L7_Tln_Block;
   BytePtr = 0;
   while ( BytePtr < GesamtLen )
   {
   	 Cmd.param[1] = BytePtr;
     if ( (BytePtr + BlockLen) <= GesamtLen )
       Cmd.param[2] = BlockLen;
     else
       Cmd.param[2] = GesamtLen - BytePtr;
     i = 3;  
     do
     {  
       ConfPbxPutAndGet (Cmd, daten, text, 0);
       BinLen = ChangeStringToBinary (daten, text);
     }while ( BinLen != Cmd.param[2] && i-- );  
     if ( i == 0 )
       printf ("Error: BinLen=%d\n", BinLen);
     ReadLen += BinLen;
     memcpy ( root, text, BinLen );
     root += BinLen;
     BytePtr += Cmd.param[2];
     printf ("%4d Bytes\n", ReadLen);
   }
   
   strcpy (Cmd.befehl, "ENDE");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "BYE", 3) != 0)
     return (ret);

   MakeTlnFile ( L7_Tln_Block );
   ret = NO_ERROR;
   return (ret);
}

/*****************************************************************************/
/* Funktion fuer die lesende Uebertragung des IDAT-Blocks                    */
/* ----------------------------------------------------------------------    */
/* In:	void                                                                 */
/* ---------------------------------------------------                       */
/* Out:	NO_ERROR wenn die Operation geklappt hat, sonst ERROR                */
/* ----------------------------------------------------                      */
/* Autor: Th. Marquardt                                                      */
/* letzte Aenderung: Th. Marquardt 17.11.2000                                */
/*****************************************************************************/
int GetL7IntPortTab ( INT_PORT_TAB L7_IntPortTab )
{
   int BinLen = 0;
   int GesamtLen = sizeof (INT_PORT_TAB);
   int BytePtr;
   int i, ReadLen = 0;
   unsigned char *daten = malloc(512);
   unsigned char *text  = malloc(512);
   unsigned char *root;
   int ret = ERROR;	
   cmdtype Cmd;	


   printf ("\nLese L7_Tln_Block Groesse=%d\n", GesamtLen);

   memset (&L7_IntPortTab, 0x00, sizeof (L7_IntPortTab));
   
   strcpy (Cmd.befehl, "I209");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "OK", 2) != 0)
     return (ret);

   strcpy (Cmd.befehl, "IDAT");
   Cmd.param_anz = 3;
   Cmd.param[0] = 1;
   root = (void *)&L7_IntPortTab;
   BytePtr = 0;
   while ( BytePtr < GesamtLen )
   {
   	 Cmd.param[1] = BytePtr;
     if ( (BytePtr + BlockLen) <= GesamtLen )
       Cmd.param[2] = BlockLen;
     else
       Cmd.param[2] = GesamtLen - BytePtr;
     i = 3;  
     do
     {  
       ConfPbxPutAndGet (Cmd, daten, text, 0);
       BinLen = ChangeStringToBinary (daten, text);
     }
		 while ( BinLen != Cmd.param[2] && i-- );  
     if ( i == 0 )
       printf ("Error: BinLen=%d\n", BinLen);
     ReadLen += BinLen;
     memcpy ( root, text, BinLen );
     root += BinLen;
     BytePtr += Cmd.param[2];
     printf ("%4d Bytes\n", ReadLen);
   }
   
   strcpy (Cmd.befehl, "ENDE");
   Cmd.param_anz = 0;
   ConfPbxPutAndGet (Cmd, daten, text, 0);
   if (strncmp(text, "BYE", 3) != 0)
     return (ret);

   MakeTabFile ( L7_IntPortTab );
   ret = NO_ERROR;
   return (ret);
}

