
/***************************************************************************
                          decode.c  -  description
                             -------------------
    begin                : Thu Dec 9 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 K_LGB_KOMMEND    0
#define K_LGB_GEHEND     1
#define K_LGB_RUFABBRUCH 2

typedef struct GespDatStruct
{
  byte Status;
  byte DateYear;
  byte DateMonth;
  byte DateDay;
  byte TimeHour;
  byte TimeMinute;
  byte DurationHours;
  byte DurationMinutes;
  byte DurationSeconds;
  byte Dir;
  byte Units;
  byte ValueDM;
  byte ValuePF;
  byte SubscriberNo;
  byte S0Port;
  byte SubscriberPort;
  byte MsnIndex;
} GespDatType;

/*-FUNKTION-**************************************************************************************/
/* Funktionsname   : L 0 _ T M _ N i b b l e _ W a h l z i f f e r                               */
/*-----------------------------------------------------------------------------------------------*/
/* Aufgabe         : Jeweils zwei Wahlziffern werden in ein Byte gepackt. Eine Wahlziffer Null   */
/*                   wird mit dem Wert 10 gespeichert, * mit 11 und # mit 12.                    */
/*                                                                                               */
/* Eingabe-Param.  : dest: Zieladresse fuer die konvertierten Daten                              */
/*                   src:  Quelladresse fuer die Daten die konvertiert werden sollen             */
/*                   size: Anzahl der Bytes die umgewandelt werden sollen                        */
/* Return-Wert     : Neue Laenge der Daten                                                       */
/*                                                                                               */
/* Info            :                                                                             */
/*************************************************************************************************/

word L0_TM_NibbleWahlziffer ( byte *dest, byte *src, word size )
{
  byte temp;
  word n_src = 0;
  word n_dest = 0;
  byte i;
  
  while ( n_src < size )
  {
    for (i = 0; i <= 1; i++)
    {
      temp = src[n_src++];
      switch ( temp )
      {
        case 0:
          temp = 0;
        break;
        case '0':
          temp = 0x0A ;                                  
        break;
        case '*':
          temp = 0x0B ;                                  
        break;
        case '#':
          temp = 0x0C ;                                  
        break;
        default:
          temp -= 0x30;
        break;
      }
      if ( i == 0 )
        dest[n_dest] = temp;
      else  
        dest[n_dest++] |= (temp << 4);
    }
  }
  return( n_dest );
}


/*-FUNKTION-**************************************************************************************/
/* Funktionsname   : L 0 _ T M _ D e c o m p _ W a h l z i f f e r                               */
/*-----------------------------------------------------------------------------------------------*/
/* Aufgabe         : Wahlziffern werden aus einem Byte entpackt. Mit der Funktion                */
/*                   NibbleWahlziffer werden sie gepackt.                                        */
/*                                                                                               */
/* Eingabe-Param.  : dest: Zieladresse fuer die konvertierten Daten                              */
/*                   src:  Quelladresse fuer die Daten die konvertiert werden sollen             */
/*                   size: Anzahl der Bytes die umgewandelt werden sollen                        */
/* Return-Wert     : Neue Laenge der Daten                                                       */
/*                                                                                               */
/* Info            :                                                                             */
/*************************************************************************************************/

word L0_TM_DecompWahlziffer ( byte *dest, byte *src, word size )
{
  byte temp, ziff;
  word n_src = 0;
  word n_dest = 0;
  byte i;
  
  while ( n_src < size )
  {
    temp = *src++;
    n_src++;
    for (i = 0; i <= 1; i++)
    {
      if ( i == 0 )
        ziff = (byte)(temp & 0x0F);
      else
        ziff = (byte)((temp & 0xF0) >> 4);
      switch ( ziff )
      {
         case 0:
          *dest = 0;
         break;
         case 0x0A:
          *dest = '0';
         break;
         case 0x0B:
          *dest = '*';
         break;
         case 0x0C:
          *dest = '#';
         break;
         default:
          *dest = (byte)(ziff + 0x30);
         break;
      }    
      dest++;
      n_dest++;
    }
  }
  return( n_dest );
}




/*****************************************************************************/
/* Funktion zur Decodierung und Ausgabe der Gesprächsdaten (siehe gesp.doc)  */
/* ----------------------------------------------------------------------    */
/* In:	Data - Zeichenkette in ASCII-Data (muss in Binär gewandelt werden)   */
/*      gsp_fd - Filedescriptor fuer GSP-Data-File                           */
/* ---------------------------------------------------                       */
/* Out:	void                                                                 */
/* ----------------------------------------------------                      */
/* Autor: Th.Marquardt                                                       */
/* letzte Aenderung: Steffen Hildebrandt, 11.11.2002                         */
/*****************************************************************************/
void ShowGespDat ( unsigned char * Data, FILE *gsp_fd )
{
  GespDatType GespDat;
  byte i;
  byte j;
  byte zw1;
  byte zw2;
  byte ByteAnzahl;
  byte Rufnummernlaenge;
  byte ByteNr;
  unsigned char Rufnummer[0x20];
  unsigned char HilfsString[0x10];
  unsigned char Data_p[0x100];
  unsigned char DirString[0x10];
  unsigned char *temp_string = calloc(128, 1);


  ByteAnzahl = strlen ( Data );
  strcpy (Data_p, "");
  j = 0;
  for ( i = 0; i < (ByteAnzahl / 2); i++)
  {
    strncpy (HilfsString, Data, 2);
    HilfsString[2] = '\0';
    Data_p[j++] = (byte)(HexToWert(HilfsString));
    Data += 2;
  }
  ByteAnzahl = j;

  #ifdef MARQ_TEST
    SosPrintf ("GespBytes: Anzahl= %d \n",ByteAnzahl );
    for ( i = 0; i < ByteAnzahl; i++ )
      SosPrintf("%02x ", Data_p[i] );
    printf ("\n");
  #endif

  memset ( &GespDat, 0x00, sizeof(GespDatType) );
  zw1 = (Data_p[ 1]);
  GespDat.Dir = (byte)((zw1 >> 4) & 0x07);
  Rufnummernlaenge = (byte)(Data_p[1] & 0x0F);

  GespDat.DateDay = (byte)( (Data_p[2] >> 2) & 0x1F );
  zw1 = (byte)( (Data_p[2] & 0x03) << 2);
  zw2 = (byte)( (Data_p[3] >> 5) & 0x03);
  GespDat.DateMonth = (byte)(zw1 | zw2);
  zw1 = (byte)( (Data_p[3] << 2) & 0x7F );
  zw2 = (byte)( (Data_p[4] >> 5) & 0x03);
  GespDat.DateYear = (byte)(zw1 | zw2);
  GespDat.TimeHour = (byte)(Data_p[4] & 0x1F);
  GespDat.TimeMinute = (byte)((Data_p[5]>>1) & 0x3F);

  /* --- Status --- */
  GespDat.Status = (byte)( Data_p[5] & 0x01 );

  ByteNr = 6;
  if ( GespDat.Dir == K_LGB_KOMMEND || GespDat.Dir == K_LGB_GEHEND )
  {
    GespDat.DurationHours = Data_p[6];
    GespDat.DurationMinutes = (byte)((Data_p[7] >> 1) & 0x3F);
    zw1 = (byte)( (Data_p[8] >> 2) & 0x1F);
    zw2 = (byte)( (Data_p[7] << 5) & 0x20);
    GespDat.DurationSeconds = (byte)( zw1 | zw2 );
    ByteNr = 9;
  }
  if ( GespDat.Dir == K_LGB_GEHEND )
  {
    /* --- Einheiten --- */
    GespDat.Units = (word)( ((Data_p[8] & 0x03)<< 8) | (Data_p[9] << 1) | ( (Data_p[10] >> 6) & 0x01 ) );
    GespDat.ValueDM = (word)( (Data_p[11] >> 3) | ( (Data_p[10] & 0x3F) << 4 ) );
    GespDat.ValuePF = (word)( ((Data_p[12] >> 3) & 0x0F) | ( (Data_p[11] & 0x07) << 4 ) );
    ByteNr = 13;
  }
  /* Keine Rufnummer dekomprimiert */
  strcpy (Rufnummer, "");
  for (i = ByteNr; i < (ByteNr+Rufnummernlaenge); i++)
  {
    /* if ( i == (ByteNr+Rufnummernlaenge-1) && ((Data_p[i] & 0x70) == 0x70) ) */
    if ( (Data_p[i] >> 4) == 0x07 )
      sprintf (HilfsString, "%1d", (Data_p[i] & 0x0F));
    else
      sprintf (HilfsString, "%02d", Data_p[i]);
    strcat (Rufnummer, HilfsString);
  }
  ByteNr = (byte)(ByteNr + Rufnummernlaenge );

  GespDat.SubscriberNo = Data_p[ByteNr];
  GespDat.S0Port = (byte)( (Data_p[ByteNr + 1] >> 5) & 0x03 );
  zw1 = (byte)( (Data_p[ByteNr + 1] << 1) & 0x3E );
  zw2 = (byte)( (Data_p[ByteNr + 2] >> 6) & 0x01 );
  GespDat.SubscriberPort = (byte)( zw1 | zw2 );
  GespDat.MsnIndex = (byte)( Data_p[ByteNr + 2] & 0x3F );

  switch ( GespDat.Dir )
  {
     case K_LGB_KOMMEND:
       strcpy (DirString, "in   ");
     break;
     case K_LGB_GEHEND:
       strcpy (DirString, "out  ");
     break;
     case K_LGB_RUFABBRUCH:
       strcpy (DirString, "call ");
     break;
     default:
       sprintf (DirString, "%02x   ", GespDat.Dir);
     break;
  }

  printf ("%02d.%02d.%02d  %s  ", GespDat.DateDay, GespDat.DateMonth, GespDat.DateYear, DirString);
	sprintf(temp_string, "%02d.%02d.%02d  %s  ", GespDat.DateDay, GespDat.DateMonth, GespDat.DateYear, DirString);
	fputs(temp_string, gsp_fd);

  if ( GespDat.Dir == K_LGB_RUFABBRUCH )
	{
     printf ("--  ");
		 fputs("--  ", gsp_fd);
	}
   else
	{
     printf ("%02d  ", GespDat.SubscriberNo);
		 sprintf(temp_string, "%02d  ", GespDat.SubscriberNo);
		 fputs(temp_string, gsp_fd);
	}

  printf ("%25s  %2d:%02d  ", Rufnummer, GespDat.TimeHour, GespDat.TimeMinute);
	sprintf(temp_string, "%25s  %2d:%02d  ", Rufnummer, GespDat.TimeHour, GespDat.TimeMinute);
  fputs(temp_string, gsp_fd);

  if ( GespDat.Dir == K_LGB_RUFABBRUCH )
	{
     printf ("                      ");
		 fputs("                      ", gsp_fd);
	}
   else
  {
     printf ("%2d:%02d:%02d  ", GespDat.DurationHours, GespDat.DurationMinutes, GespDat.DurationSeconds);
		 sprintf(temp_string, "%2d:%02d:%02d  ", GespDat.DurationHours, GespDat.DurationMinutes, GespDat.DurationSeconds);
     fputs(temp_string, gsp_fd);
     if ( GespDat.Dir == K_LGB_KOMMEND )
		 {
        printf ("            ");
        fputs("            ", gsp_fd);
		 }
      else
     {
        printf ("%3d  %2d,%02d  ", GespDat.Units, GespDat.ValueDM, GespDat.ValuePF);
				sprintf(temp_string, "%3d  %2d,%02d  ", GespDat.Units, GespDat.ValueDM, GespDat.ValuePF);
        fputs(temp_string, gsp_fd);
		 }
  }
  printf ("%1d  %1d\n", GespDat.S0Port, GespDat.MsnIndex);
	sprintf(temp_string, "%1d  %1d\n", GespDat.S0Port, GespDat.MsnIndex);
  fputs(temp_string, gsp_fd);

	fflush(gsp_fd);

	return;
}






















