#!/bin/bash
###############################################################################################################
# Titel: sds2db
# Autor: Michael Kaden
# Datum: 06.03.2015
#
# Funktion:
# Dieses Skript ist ein Teilprogramm von sds2db. Es liest alle im Read-Spooler-Verzeichnis erzeugten Dateien
# in einer Endlosschleife ein. 
# Diese Read-Spooler-Dateien enthalten jeweils eine Zeile, die durch die Read-Spooler von dem an der jeweiligen 
# seriellen (RS232) Schnittstelle angeschlossenen Gert empfangen haben.
# Alle empfangenen Zeilen werden, um Log-Informationen erweitert, in ein Logfile geschrieben.
# Empfangene Zeilen, die als "CTSDSR unsolicited Result Codes" eines TETRA MT erkannt werden, werden gem 
# ETSI EN 300 392-5 als SDS interpretiert und im Rohformat in eine MySQL-Datenbank geschrieben.
# Wenn konfiguriert, werden die SDS-Bestandteile an ein "externes" Programm zur weiteren Dekodierung bergeben.
# Die Protokolle Text Messaging(3,130), LIP(3,10) und Status(2,20) werden zu diesem Zweck bei der 
# Initialisierung jeder konfigurierten Schnittstelle, auf der SDS2DB lauscht, fr das Routing zum TE registriert.
#
# Zweck:
# Das Script soll als Hintergrundprozess auf einem Statusmonitor-PC laufen, der mittels RS232-Schnittstellen (auch 
# USB/Seriell-Konverter oder Ethernet-Serial-Device-Server) mit einem PEI-Interface eines TETRA Funkgertes verbunden ist. 
# Die in der MySQL-Datenbank gesammelten SDS knnen so in anderen Anwendungen, z.B. Einsatzfhrungssoftware, ausgewertet 
# werden, um z.B. Status-, Positions- oder Text-Informationen zu verarbeiten.
#
# Copyright (C) 2015 Michael Kaden
#
# Dieses Programm ist freie Software. Sie knnen es unter Beachtung der Nutzungsbedingungen benutzen, 
# weitergeben und modifizieren.
# Die Verffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, 
# aber OHNE IRGENDEINE GARANTIE, sogar ohne die Garantie der MARKTREIFE oder der VERWENDBARKEIT FR EINEN 
# BESTIMMTEN ZWECK. 
###############################################################################################################

# Config-File einlesen
source /usr/local/sds2db/etc/sds2db.conf

myname=$(echo $0 | $awkbin -F/ '{ print $NF }')

# alle Dateien des read spoolers im Spoolverzeichnis in einer Endlosschleife einlesen
$inotifybin -mq -e create $readspooldir --format '%f' | while read file; do
  if [ -n "$file" ]; then

	# Device bestimmen, von dem die Daten stammen
	device="$(echo $file | $awkbin -F. '{ print $NF }')"

	# Inhalt der Spooldatei in Variable bernehmen und Zeilenumbrche entfernen
	logline="$(tail -n1 "$readspooldir/$file" | tr -d '\r\n')"
	
	# Alle Zeilen die nicht leer sind ins Logfile schreiben
	if [ -n "$logline" ]; then
	       echo "$(date +"%b %d %H:%M:%S") $host $skriptname: rx $logline" >> $logdir/$device.log
	fi

	# wenn die empfangene Zeile einen SDS-Header enthlt, der durch "+CTSDSR:" gekennzeichnet ist
	if [ `echo "$logline" |grep -c "+CTSDSR:"` -eq '1' ]; then
		
		# erzeuge ein Array fr die Schnittstelle des angeschlossenen Funkgertes um den SDS-Header fr den nchsten Skriptlauf zu sichern
		declare -A ${device}
		# beflle die entsprechenden Array-Elemente
		eval $device[header]="$(echo $logline | $awkbin '{ print $2 }')"
		eval $device[device]=$device
		eval $device[service_type]=$(echo $(eval echo \${$device[header]}) | $awkbin -F, '{ print $1 }')
		eval $device[from]=$(echo $(eval echo \${$device[header]}) | $awkbin -F, '{ print $2 }')
		eval $device[from_type]=$(echo $(eval echo \${$device[header]}) | $awkbin -F, '{ print $3 }')
		eval $device[to]=$(echo $(eval echo \${$device[header]}) | $awkbin -F, '{ print $4 }')
		eval $device[to_type]=$(echo $(eval echo \${$device[header]}) | $awkbin -F, '{ print $5 }')
		eval $device[length]=$(echo $(eval echo \${$device[header]}) | $awkbin -F, '{ print $6 }')
		
		#log "$myname($device)" "$(eval echo \${$device[device]}) in \$use_recv_issi_whitelist: $(echo "$use_recv_issi_whitelist" | grep -c "$(eval echo \${$device[device]})")"

		# wenn die Whitelist konfiguriert ist und der Absender nicht in der Whitelist gelistet ist, wird das Array zurckgesetzt
		if ([ "$(echo "$use_recv_issi_whitelist" | grep -c "$(eval echo \${$device[device]})")" = "1" ] && [ ! -e "$recv_whitelist_rundir/$(eval echo \${$device["from"]})" ]); then
			#log "$myname($device)" "unset ${device}"
			unset ${device}
		fi

	# Wenn das Array gesetzt ist(weil vorher ein SDS-Header empfangen wurde) und diese Zeile vom selben FuG kommt, 
	# empfangen wir jetzt die SDS user data
	elif [ "$(eval echo \${$device[device]})" = "$device" ]; then
			
		# sichere die SDS user data in entsprechendem Array-Element
		eval $device[user_data]="$logline"
		log "$myname($device)" "SDS AI service \"$(eval echo \${$device[service_type]})\" empfangen von \"$(eval echo \${$device[from]})\" an \"$(eval echo \${$device[to]})\""

		#log "$myname" "SDS user data \"$(eval echo \${$device["user_data"]})\""

		# bergebe die SDS an ein externes Programm, wenn dies in der Konfiguration aktiviert ist
		if ([ "$use_ext_program" = "yes" ] && [ -e "$ext_program" ]); then
			log "$myname($device)" "SDS weiterleiten an \"$ext_program\""
			"$ext_program" "$(eval echo \${$device[device]}),$(eval echo \${$device[service_type]}),$(eval echo \${$device[from]}),$(eval echo \${$device[from_type]}),$(eval echo \${$device[to]}),$(eval echo \${$device[to_type]}),$(eval echo \${$device[length]}),$(eval echo \${$device[user_data]})" &
		fi

		# SDS-Datensatz in Datenbank schreiben
		exec_mysql "INSERT INTO $db_sds_table (sds_time,sds_service_type,sds_from,sds_from_type,sds_to,sds_to_type,sds_length,sds_user_data,sds_hostname) values (NOW(),'$(eval echo \${$device[service_type]})','$(eval echo \${$device[from]})','$(eval echo \${$device[from_type]})','$(eval echo \${$device[to]})','$(eval echo \${$device[to_type]})','$(eval echo \${$device[length]})','$(eval echo \${$device[user_data]})','$host')"
		mysqlexit=$?
		# > /dev/null 2>&1
		#echo "\$mysqlexit: $mysqlexit"
		if (( $mysqlexit == 0 )); then
			log "$myname($device)" "SDS in Datenbank geschrieben"
		else
			log "$myname($device)" "Fehler beim Schreiben in die Datenbank"
		fi
			
		unset ${device}

	# wenn ein TETRA-MT eingeschaltet wird, nachdem das Script bereits gestartet wurde, wird "init" erneut aufgerufen, um das TE fr die 
	# ntigen Message-PIDs zu registrieren
	elif [ `echo "$logline" |grep -c "+CTOM:"` -eq '1' ]; then
		log "$myname($device)" " ausfhren von \"$programdir/$inithelper start $device\""
		$programdir/$inithelper start $device 

		# zur Identittsbestimmung des angeschlossenen Funkgertes werden beim Initialisieren die "fixed TETRA Identities" ausgelesen 
	elif [ `echo "$logline" |grep -c "+CNUMF: 0"` -eq '1' ]; then
		echo $(((10#$(echo $logline | $awkbin -F, '{ print substr($2 ,length($2)-7,8) }')*1))) > $runfiledir/$device.issi

		# Bestimmung der gewhlten Gruppe
	elif [ `echo "$logline" |grep -c "+CTGS:"` -eq '1' ]; then
		echo $(((10#$(echo $logline | $awkbin -F, '{ print substr($2 ,length($2)-7,8) }')*1))) > $runfiledir/$device.gssi

		# Bestimmung der OPTA
	elif [ $(echo "$logline" |grep -c "+SIM: 3,") -eq '1' ]; then
		echo $(echo $logline | $awkbin -F, '{ print $2 }') > $runfiledir/$device.opta
	fi
    fi
    unset logline
    unset device
    unset mysqlexit
    # Spooldatei lschen
    rm "$readspooldir/$file"
done 
exit 0

