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

    begin                : Fri Nov 17 16:41:45 MET 2000

    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.                                   *
 *                                                                         *
 ***************************************************************************/

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


/*
 * letzte Aenderung am  : 15.04.2003
 *                  von : Steffen Hildebrandt
 */

/* geskoctrl Version 0.3.2 */

int hv = 0;
int uv = 3;
int rv = 2;
//int pv = 1;

//char *zi="- beta1";
char *zi="";

char *vd = "15.04.2003";


/*
 * History -> siehe ChangeLog!
 *
 */


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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <termios.h>
#include <unistd.h>
#include <signal.h>

#include "gesko.h"


typedef struct GebStruct
{
   byte   mode ATT;
   word   dm ATT;
} GebType;


/* globale Variablen */
int	PBXHandle = 0; 					/* Handle des offenen Devices z.B für /dev/cua0 */
int timer, timeout_mode, timeout;
int fw_dld;
int logging;
extern unsigned char device[];
unsigned char *datei_old = "firmware.old";
int fw_ger_aus_ow = FALSE;


/* Main-Funktion */
int main ( int argc, char *argv[] )
{
  int i, j;
  int com, end, Answer = ERROR;
  cmdtype Cmd;
  EINRICHT_BLOCK L7_Einr_Block;
  MSN_BLOCK      L7_Msn_Block;
  TLN_BLOCK      L7_Tln_Block;
  INT_PORT_TAB   L7_IntPortTab;
  unsigned char *daten = malloc(512);
  unsigned char *text = malloc(512);
  unsigned char *datei = malloc(64);
  unsigned char *puffer = malloc(512);
  unsigned char *buf = malloc(512);
  unsigned char *temp = malloc(512);
  int baud = 19200;												/* Standardbaudrate 19200 Baud */
  int baud_param = 0;


  #ifdef TEST
	  GebType g;
	  unsigned char * x;

	  g.mode = 1;
	  g.dm = 2;

	  x = (void *)&g;
	  for ( i=0 ; i<sizeof(GebType); i++)
   		printf ("%02x  ", *x++);
	  printf ("\n%d\n", g.mode);	
	  printf ("%d\n", g.dm);	
	  exit (0);	
  #endif
  
  if(argc == 1)
  {
    HelpText();
    exit (0);
  }

  /* Struktur fuer Befehlsparameter initialisieren */
  memset ( (void *)&Cmd, 0x00, sizeof(cmdtype) );

  /* Pruefen, ob geskoctrl schon gestartet wurde */
  CheckStartProgram();

	logging = FALSE; 

	/* Signalhandler für diverse Signale SIG... installieren */
	signal(SIGABRT, EndeProgrammSignal);
	signal(SIGKILL, EndeProgrammSignal);
	signal(SIGSEGV, EndeProgrammSignal);
	signal(SIGTERM, EndeProgrammSignal);
	signal(SIGINT, EndeProgrammSignal);

  /* Signalhandler für Timerablauf generieren */
 #ifdef TIMEOUT
	signal(SIGALRM, TimerEnd);
   #ifdef DEBUG
    printf("Signalhandler fuer Timerablauf (SIGALRM) generiert.\n");
   #endif
 #endif

  /* schauen, welche serielle Schnittstelle gewünscht ist */
  if( strncmp(argv[1], "-com", 4) != 0)
  {

    /* --- Ausgabe der Programmversion --- */
    /* ----------------------------------- */
    if ( strncmp(argv[1], "-v", 2) == 0 )
    {
      CopyrightText();

      return EXIT_SUCCESS;
    }

    /* --- Ausgabe der Hilfe --- */
    /* ------------------------- */
    if ( strncmp(argv[1], "-h", 2) == 0 )
    {
      HelpText();

      return EXIT_SUCCESS;
    }

    /* oder Ende... */   
    else
    { 
      printf("FEHLER : Keine Angabe der seriellen Schnittstelle (Com1...4)! -> ABBRUCH!\n");
      printf("\n -> geskoctrl -com <Nr./device>...\n\n");
      exit (0);
    }
  }
   else
  {
    if(argc == 2)
    {
      printf("FEHLER : Nr. der seriellen Schnittstelle nicht angegeben! -> ABBRUCH!\n");
      exit (0);
    }

    if(argc == 3)
    {
      printf("FEHLER : Kein Befehl oder keine Option angegeben! -> ABBRUCH!\n");
      exit (0);
    }

		/* Angabe der seriellen Schnittstelle als device */
		if(strncmp(argv[2], "/dev/", 5) == 0)
			SetDevice ( 0, argv[2], COM_DEVICE );
		 else
		{
		/* Angabe der seriellen Schnittstelle als Nummer -> Defaultdevices werden genutzt */
    	com = atoi(argv[2]);    
    	SetDevice ( com, NULL, COM_NUMBER );
		}
  }

  /* Schnittstelle mit Standard-Baudrate von 19200 Baud oeffnen */
  Answer = PbxOpen();
  if(Answer != NO_ERROR)
  {
    printf ("FEHLER: Oeffnen serielle Schnittstelle -> ABBRUCH!\n");
    exit (0);
  }


/* -------------------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------------------------- */

  /* Bei folgenden Befehlen ist eine Einstelleung der PC-Baudrate nicht moeglich! */

  /* --- Es soll die Firmware im GT-Datenformat uebertragen werden --- */
  /* ----------------------------------------------------------------- */
  if ( strncmp(argv[3], "-d", 2) == 0 )
  {
	   if ( argc > 3 )
   		 sprintf ( datei, "%s", argv[4] );
	   else
     {
       printf("FEHLER : Keine Firmware-Datei angegeben! -> ABBRUCH\n");
       exit (0);
     }

     /* schauen, welche Baudrate */
     if(argc > 5 && strncmp(argv[5], "-b", 2) == 0)
       baud = atoi(argv[6]);
      else
       baud = 19200;

     if(baud == 9600)                /* Baudratenumstellung nur fuer Baudrate von 9600 Baud -> alte Anlagen */
       SetPcBaudRate(baud);

     Answer = GetAnlageTyp();

     if(Answer == FAMILY_OLD || Answer == OFFICE_OLD)
     {
       printf("HINWEIS : Firmware-Download mit diesen Anlagen nicht moeglich! -> ABBRUCH!\n");
       exit(0);
     }
      else
     {
       /* Darf FW Deutschland <-> Oesterreich ueberschrieben werden? */
       for(j = 0; j < argc; j++)
       {
         if(strncmp(argv[j], "-ow", 3) == 0)
         {
          #ifdef DEBUG
           printf("FW D <-> A darf ueberschrieben werden...\n");
          #endif
           fw_ger_aus_ow = TRUE;
         }
       }
       Answer = GTFirmwareDownload ( baud, datei );
     }

     return EXIT_SUCCESS;
  }


  /* --- Aktuelle Firmware aus PBX auslesen und in ein File schreiben --- */
  /* -------------------------------------------------------------------- */
  if ( strncmp(argv[3], "-f", 2) == 0 )
  {
		 /* Dateinamen ermitteln, oder Default-Name angeben */
     if ( argc == 4 )
   	   sprintf ( datei, "%s", datei_old );

     if ( argc > 4 )
	     sprintf ( datei, "%s", argv[4] );

     /* schauen, welche Baudrate */
     if(argc > 5 && strncmp(argv[5], "-b", 2) == 0)
       baud = atoi(argv[6]);
      else
       baud = 19200;

     if(baud == 9600)                /* Baudratenumstellung nur fuer Baudrate von 9600 Baud -> alte Anlagen */
       SetPcBaudRate(baud);

     Answer = GetAnlageTyp();

     if(Answer == FAMILY_OLD || Answer == OFFICE_OLD)
     {
       printf("HINWEIS : Firmware-Upload mit diesen Anlagen nicht moeglich! -> ABBRUCH!\n");
       exit(0);
     }
      else
	     Answer = GTFirmwareUpload ( baud, datei );

     return EXIT_SUCCESS;
  }


  /* --- Es soll was im GT-Datenformat uebertragen werden --- */
  /* -------------------------------------------------------- */
  if ( strncmp(argv[3], "-a", 2) == 0 )
  {
    printf("Befehl im GT-Format...\n");

	  if ( argc > 3 )
	  {
      sprintf ( Cmd.befehl, "%s", argv[4] );
      for (i = 0; i < strlen(Cmd.befehl); i++)
        Cmd.befehl[i] = toupper(Cmd.befehl[i]);
	  }
	  else
   		return (0);

    /* schauen, welche Baudrate */
    if(argc > 5)
      baud = atoi(argv[6]);
     else
      baud = 19200;

    if(baud == 9600)                /* Baudratenumstellung nur fuer Baudrate von 9600 Baud -> alte Anlagen */
      SetPcBaudRate(baud);

    Answer = GetAnlageTyp();

    if(Answer == FAMILY_OLD || Answer == OFFICE_OLD)
    {
      printf("HINWEIS : GT-Befehle mit diesen Anlagen nicht moeglich! -> ABBRUCH!\n");
      exit(0);
    }
     else
    {
      if(Answer == FAMILY)
      {
        ReadFirmwareVersion(puffer, buf, FALSE);                     /* FW-Version der family-Anlagen ueberpruefen */

	      strncpy(temp, strpbrk(buf, "V"), 5);

        /* GT-befehle erst ab FW-Version V4.22 moeglich! */
	      if(strcmp(temp, "V4.21") <= 0)
	      {
		      printf("HINWEIS : GT-Befehle bei Anlagen der family-Reihe erst ab FW-Version >= V4.22 moeglich! -> ABBRUCH!\n");
		      exit(0);
	      }	
      }

      Answer = GTPbxPutAndGet ( Cmd, text, 1 );
    }

    return EXIT_SUCCESS;
  }

/* -------------------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------------------------- */

  /* Bei folgenden Befehlen ist eine Einstelleung der PC-Baudrate moeglich! */


  /* --- PC-Baudrate ermitteln und einstellen --- */
  /* -------------------------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-b", 2) == 0)
    {
       baud = atoi(argv[j + 1]);

     #ifdef DEBUG
       printf ("argc=%d     argv[%d]=%s     baud=%d\n", argc, j + 1, argv[j + 1], baud);
     #endif

       SetPcBaudRate(baud);

       baud_param = j;      /* merken, an welcher Stelle "-b" aufgetreten ist */
    }
  }

  /* --- Es soll was im Konfigurations-Datenformat uebertragen werden --- */
  /* -------------------------------------------------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-n", 2) == 0)
    {

       printf("Befehl im CONF-Format...\n");

       Cmd.param_anz = 0;

       if(j > baud_param && baud_param != 0)          /* Baudratenbefehl vor dem CONF-Befehl */
       {
        #ifdef DEBUG
         printf("Parameter fuer Baudrate vor dem CONF-Befehl...\n");
        #endif

			   if(argc > 5)
			   {
				   sprintf(Cmd.befehl, "%s", argv[j + 1]);

				   for (i = 0; i < strlen(Cmd.befehl); i++)
					   Cmd.befehl[i] = toupper(Cmd.befehl[i]);
			   }

			   if(argc == 6)
			   {
				   printf("FEHLER : Kein CONF-Befehl angegeben! -> ABBRUCH\n");
				   exit (0);
			   }
 
			   if(argc > 7)
			   {
				   Cmd.param_anz = argc - 7;

				   if(argc <= 10)
					   end = argc - 7;
				    else
					   end = 10 - 7;

				   for(i = 0; i < end; i++)
					   Cmd.param[i] = strtoul(argv[i + 5], NULL, 16);
			   }

			   if(argc > 10)
			   {
				   sprintf(Cmd.daten, "%s", argv[10]);
				   Cmd.data_len = strlen(Cmd.daten);
			   }
       }
        else                      /* Baudratenbefehl nach dem CONF-Befehl oder ist nicht angegeben */
       {
        #ifdef DEBUG
         printf("Parameter fuer Baudrate nach dem CONF-Befehl oder ist nicht angegeben...\n");
        #endif
	       if(argc > 3)
			   {
				   sprintf(Cmd.befehl, "%s", argv[j + 1]);

				   for (i = 0; i < strlen(Cmd.befehl); i++)
					   Cmd.befehl[i] = toupper(Cmd.befehl[i]);
			   }

			   if(argc == 4)
			   {
				   printf("FEHLER : Kein CONF-Befehl angegeben! -> ABBRUCH\n");
				   exit (0);
			   }
 
			   if(argc > 5)
			   {
				   Cmd.param_anz = argc - 5;

				   if(argc <= 8)
					   end = argc - 5;
				    else
					   end = 8 - 5;

				   for(i = 0; i < end; i++)
					   Cmd.param[i] = strtoul(argv[i + 5], NULL, 16);
			   }

			   if(argc > 8)
			   {
				   sprintf(Cmd.daten, "%s", argv[8]);
				   Cmd.data_len = strlen(Cmd.daten);
			   }
       }

	     Answer = ConfPbxPutAndGet(Cmd, daten, text, 1);

   	   return EXIT_SUCCESS;
    }
  }


  /* --- Es sollen die Gespraechsdaten gelesen werden --- */
  /* ---------------------------------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-ga", 3) == 0)
    {

	   #ifdef GET_GSPDATA_GT	
	    Answer = GespGtPbxPutAndGet(GSPDATA_APPEND);
	   #endif
	   #ifdef GET_GSPDATA_CONF
      Answer = GespConfPbxPutAndGet(GSPDATA_APPEND);
	   #endif

      return EXIT_SUCCESS;
    }

    if(strncmp(argv[j], "-g", 2) == 0)
    {

	   #ifdef GET_GSPDATA_GT	
	    Answer = GespGtPbxPutAndGet(GSPDATA_NEW);
	   #endif
	   #ifdef GET_GSPDATA_CONF
      Answer = GespConfPbxPutAndGet(GSPDATA_NEW);
	   #endif

      return EXIT_SUCCESS;
    }
  }


  /* --- Es sollen die Konfigurationsdaten gelesen und in ein File geschrieben werden --- */
  /* ------------------------------------------------------------------------------------ */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-r", 2 ) == 0)
    {

		  system("rm config_data/*");

      GetL7EinrBlock(L7_Einr_Block);
  	  GetL7MsnBlock(L7_Msn_Block);
	    GetL7TlnBlock(L7_Tln_Block);
	    GetL7IntPortTab(L7_IntPortTab);
	    printf( "\n");

      return EXIT_SUCCESS;
    }
  }


  /* --- PBX-Reset --- */
  /* ----------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-x", 2 ) == 0)
    {

      ResetPbx();

      return EXIT_SUCCESS;
    }
  }


  /* --- Flashkennung zerstoeren --- */
  /* ------------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-z", 2) == 0)
    {

      DestroyFlashSignature();

      return EXIT_SUCCESS;
    }
  }


  /* --- Flashkennung zerstoeren --- */
  /* ------------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-w", 2) == 0)
    {

      RepairFlashSignature();

      return EXIT_SUCCESS;
    }
  }


  /* --- Logging ueber serielle Schnittstelle --- */
  /* -------------------------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-l", 2) == 0)
    {

		  if(strncmp(argv[j + 1], "1", 1) == 0)
    	  SerialLogging(LOG_CONSOLE) ;

		  if(strncmp(argv[j + 1], "2", 1) == 0)
    	  SerialLogging(LOG_FILE);

		  if(strncmp(argv[j + 1], "3", 1) == 0)
    	  SerialLogging(LOG_CONSOLE_FILE);

      return EXIT_SUCCESS;
    }
  }


  /* --- Firmwareversion ermitteln --- */
  /* --------------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-1", 2) == 0) 
    {

      ReadFirmwareVersion(puffer, buf, FALSE);

      return EXIT_SUCCESS;
    }
  }


  /* --- Hardwareerkennung --- */
  /* ------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-2", 2) == 0)
    {

      GetHardwareInfo();

      return EXIT_SUCCESS;
    }
  }


  /* --- Anlagetyp und Firmwareversion ermitteln --- */
  /* ----------------------------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-3", 2) == 0)
    {

      Answer = GetAnlageTyp();

      if(Answer != ERROR)
        ReadFirmwareVersion(puffer, buf, FALSE);

      if(Answer != ERROR)
        GetHardwareInfo();

      return EXIT_SUCCESS;
    }
  }

  /* --- Anlagedaten auslesen --- */
  /* ---------------------------- */
  for(j = 0; j < argc; j++)
  {
    if(strncmp(argv[j], "-9", 2) == 0)
    {

      ReadPbxData();

      return EXIT_SUCCESS;
    }
  }

  /* falsche Parameter... */
  printf ("\nFEHLER: falsche(r) Parameter oder Parameterreihenfolge! -> ABBRUCH!\n");
  printf ("   -> Korrekte Baudrate angegeben?\n\n");
  
  return (0);
}

