#!/bin/bash
###############################################################################################################
# Titel: sds2db
# Autor: Michael Kaden
# Datum: 30.12.2012
#
# 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 (pei.read.ttyXXX) 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 zustzlich
# gem ETSI EN 300 392-5 als SDS interpretiert und im Rohformat in eine MySQL-Datenbank geschrieben.
# Enthlt eine SDS-TL (Type 4) eine Empfangsquittungsanforderung im Message Header, so kann eine 
# "Delivery Report"-SDS an den Absender versandt werden. Empfangene Status-SDS knnen quittiert werden, in dem der empfangene
# Status an den Absender als Status-SDS zurckgesandt wird, wenn die SDS in die DB geschrieben werden konnte.
# Die Protokolle Text Messaging(3,130), LIP(3,10) und Status(2,20) werden zu diesem Zweck bei der 
# Initialisierung jeder konfigurierten Schnittstelle, die als "FUG" konfiguriert ist 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) 2013 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

# 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
        seqnr=$RANDOM

	# 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: -> $logline" >> $logfile.$device 
	fi

	# wenn die empfangene Zeile einen SDS-Header enthlt der durch "+CTSDSR:" gekennzeichnet ist
	if [ `echo "$logline" |grep -c "+CTSDSR:"` -eq '1' ]; then
		# speichere den SDS-Header in einer Variablen
	        sds_header="$(echo $logline | $awkbin '{ print $2 }')"
		# erzeuge ein Array fr die Schnittstelle des angeschlossenen Funkgertes um den SDS-Header fr den nchsten Skriptlauf zu sichern
		SDSarray=sdshead_$device
		declare -A ${SDSarray}
		# trenne die Zeichenkette am Trennzeichen "," und weise die einzelnen Teile den entsprechenden Array-Elementen zu
		eval $SDSarray[device]=$device
		eval $SDSarray[service_type]=$(echo $sds_header | $awkbin -F, '{ print $1 }')
		eval $SDSarray[from]=$(echo $sds_header | $awkbin -F, '{ print $2 }')
		eval $SDSarray[from_type]=$(echo $sds_header | $awkbin -F, '{ print $3 }')
		eval $SDSarray[to]=$(echo $sds_header | $awkbin -F, '{ print $4 }')
		eval $SDSarray[to_type]=$(echo $sds_header | $awkbin -F, '{ print $5 }')
		eval $SDSarray[length]=$(echo $sds_header | $awkbin -F, '{ print $6 }')
		
		#for a in "${!sdshead[@]}"; do echo "$a -> ${sdshead[$a]}" >> $logfile; done
		#eval echo \${$SDSarray[from]} >> $logfile

	# wenn ein TETRA-MT eingeschaltet wird, nachdem das Script bereits gestartet wurde, wird "pei.init" erneut aufgerufen, um das TE fr die 
	# ntigen Message-PIDs zu registrieren
	elif [ `echo "$logline" |grep -c "+CTOM:"` -eq '1' ]; then
		$programdir/$inithelper $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 $logline | $awkbin -F, '{ print $2 }' > $runfiledir/$device


	# wenn die empfangene Zeile keinen SDS-Header enthlt
	else
		# 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
		if [ "$(eval echo \${$SDSarray[device]})" == "$device" ]; then
			
			# sichere die SDS user data in Variable
			sds_user_data="$logline"
			echo "$(date +"%b %d %H:%M:%S") $host $skriptname: SDS AI service \"$(eval echo \${$SDSarray[service_type]})\" empfangen von \"$(eval echo \${$SDSarray[from]})\"" >> $logfile
			echo "$(date +"%b %d %H:%M:%S") $host $skriptname: SDS user data \"$sds_user_data\"" >> $logfile
			# 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 \${$SDSarray[service_type]})','$(eval echo \${$SDSarray[from]})','$(eval echo \${$SDSarray[from_type]})','$(eval echo \${$SDSarray[to]})','$(eval echo \${$SDSarray[to_type]})','$(eval echo \${$SDSarray[length]})','$sds_user_data','$host')"
			mysqlexit=$?
			# > /dev/null 2>&1
			#echo "\$mysqlexit: $mysqlexit" >> $logfile
			if (( $mysqlexit == 0 )); then
				echo "$(date +"%b %d %H:%M:%S") $host $skriptname: SDS in Datenbank geschrieben" >> $logfile
				# Empfangsbesttigung senden, wenn angefordert
				report_request="$(echo $sds_user_data | $awkbin '{ print substr($1 ,4,1) }')"
				reference="$(echo $sds_user_data | $awkbin '{ print substr($1 ,5,2) }')"
				if [ "$(eval echo \${$SDSarray[service_type]})" = "12" ]; then
					case $report_request in
						4|5)	# received report requested (short)
							report_type="Empfangsbericht (short)"
							report_sdsparam="AT+CTSDS=12,0,0,0,1"
							#report_data="7E${reference}"
							report_data="821000${reference}"
							#report_length="16"
							report_length="32"
							;;
						6|7)	# received report requested (standard)
							report_type="Empfangsbericht (standard)"
							report_sdsparam="AT+CTSDS=12,0,0,0,1"
							report_data="821000${reference}"
							report_length="32"
							;;
						8|9)	# consumed report requested (short)
							report_type="Verarbeitungsbericht (short)"
							report_sdsparam="AT+CTSDS=12,0"
							report_data="7F${reference}"
							report_length="16"
							;;
						A|B)	# consumed report requested (standard)
							report_type="Verarbeitungsbericht (standard)"
							report_sdsparam="AT+CTSDS=12,0,0,0,1"
							report_data="821002${reference}"
							report_length="32"
							;;
						C|D)	# received and consumed report requested (short)
							report_type="Empfangs- und Verarbeitungsbericht (short)"
							report_data=""
							;;
						E|F)	# received and consumed report requested (standard)
							report_type="Empfangs- und Verarbeitungsbericht (standard)"
							report_data=""
							;;
					esac
					if ([ -n "$report_data" ] && [ $SDSdeliveryReport = "yes" ]); then
					  echo "$(date +"%b %d %H:%M:%S") $host $skriptname: SDS $report_type angefordert" >> $logfile
				          printf "${report_sdsparam}\r" > $writespooldir/$(date +%s).$(($seqnr+1)).$device
					  printf "AT+CMGS=$(eval echo \${$SDSarray[from]}),${report_length}\r\n" > $writespooldir/$(date +%s).$(($seqnr+2)).$device
					  printf "${report_data}\x1a" > $writespooldir/$(date +%s).$(($seqnr+3)).$device
					  echo "$(date +"%b %d %H:%M:%S") $host $skriptname: SDS $report_type an \"$(eval echo \${$SDSarray[from]})\" gesendet" >> $logfile
				  	fi
				fi
				# wenn Status-SDS empfangen wurde, empfangenen Status als Quittung zurck senden
				if ([ "$(eval echo \${$SDSarray[service_type]})" = "13" ] && [ $confirmStatusSDS = "yes" ]); then
					printf "AT+CTSDS=13,0\r" > $writespooldir/$(date +%s).$(($seqnr+1)).$device
					printf "AT+CMGS=$(eval echo \${$SDSarray[from]}),16\r\n" > $writespooldir/$(date +%s).$(($seqnr+2)).$device
					printf "$sds_user_data\x1a" > $writespooldir/$(date +%s).$(($seqnr+3)).$device
					echo "$(date +"%b %d %H:%M:%S") $host $skriptname: SDS Statusquittung \"$sds_user_data\" an \"$(eval echo \${$SDSarray[from]})\" gesendet" >> $logfile
				fi
			else
				echo "$(date +"%b %d %H:%M:%S") $host $skriptname: Fehler beim Schreiben in die Datenbank" >> $logfile
			fi
		unset ${SDSarray}	
		fi
	fi
    fi
	# Spooldatei lschen
	rm "$readspooldir/$file"
done 
exit 0

