#!/bin/bash
#
# ====================================================================
# The Vovida Software License, Version 1.0 
# 
# Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
#    and "Vovida Open Communication Application Library (VOCAL)" must
#    not be used to endorse or promote products derived from this
#    software without prior written permission. For written
#    permission, please contact vocal\@vovida.org.
# 
# 4. Products derived from this software may not be called "VOCAL", nor
#    may "VOCAL" appear in their name, without prior written
#    permission of Vovida Networks, Inc.
# 
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
# NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR
# PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# 
# ====================================================================
# 
# This software consists of voluntary contributions made by Vovida
# Networks, Inc. and many individuals on behalf of Vovida Networks,
# Inc.  For more information on Vovida Networks, Inc., please see
# <http://www.vovida.org/>.
#

version="\$Id: calltrace2html,v 1.2 2002/05/15 07:33:55 icahoon Exp $"


######################################################################
#
#   Load libraries
#
######################################################################

lib_path="${0%/$(basename $0)}"

. $lib_path/vocal_html_lib


log_level=$log_info

######################################################################
#
#   Local functions
#
######################################################################

function	getProtocol()
{
    assert [ $# -eq 1 ]

    log $log_verbose "get_protocol: $*"

    local rc=${1##*.}

    log $log_verbose "returns: $rc"

    $print "$rc"
}

function	getMsgType()
{
    assert [ $# -eq 1 ]

    log $log_verbose "getMsgType: $*"

    local msgType=$1

    msgType=${msgType%.*}
    msgType=${msgType%.*}
    msgType=${msgType#*.}

    local rc=${msgType#*.}

    log $log_verbose "returns: $rc"

    $print "$rc"
}

function	getDirection()
{
    assert [ $# -eq 1 ]

    log $log_verbose "getDirection: $*"

    local direction=$1

    direction=${direction%.*}

    local rc=${direction##*.}

    log $log_verbose "returns: $rc"

    $print "$rc"
}

function	getTime()
{
    assert [ $# -eq 1 ]

    log $log_verbose "getTime: $*"

    local 	time_=$1
    time_=${time_#*-}

    local	mhs=${time_%%.*}
    time_=${time_#*.}

    local 	msec=${time_%%.*}

    local rc="$mhs.$msec"

    log $log_verbose "returns: $rc"

    $print "$rc"
}

function    getPhoneNumber()
{
    log $log_verbose "getPhoneNumber: $*"
    
    local   phone_number="$*"
    
    phone_number=${phone_number#*\"}
    phone_number=${phone_number%\"*}
    
    log $log_verbose "returns: $phone_number"
    
    $print $phone_number
}

log $log_info "\nVersion: $version\nCommand: $0 $*"


#
#   Usage
#

usage="usage: $(basename $0) imagesDirectory [options]
    -g | --gkId             	gatekeeperIdentifer
    -b | --backgroundImage  	image url
    -p | --brandImage       	image url
    -n | --brandName        	name
    -l | --brankLink        	url
    -c | --calls
    -r | --registrations    	(default)
    -v | --version
    -C | --cisco  	    	Use Cisco branding
    -u | --unknown	     	Endpoint's identify is unknown"

if [ $# -eq 1 -a \( "$1" = "-v" -o "$1" = "--version" \) ]; then
    $print $version
    exit 0
fi

#
#   Image directory
#
#		Get the images directory from the command line.
#		Make a symbolic link to it.
#

assert [ $# -gt 0 ]
assert [ -d "$1" ]

image_dir="./images"
if [ ! -L $image_dir ]; then
    $ln -s $1 $image_dir || assert [ $? -eq 0 ]
fi
shift


#
#   Gatekeeper Identifier variables
#

gatekeeper_identifier=""


#
#   Background / Branding
#

background_image=""
brand_image=""
brand_name=""
brand_link=""


#
#   Call directory or registrations directory
#

calls=0

#
#   Unknown endpoint identifier
#
#   	We will generate a phone number file if this is a call (-c).
#
unknown_ept=0

#
#   Parse command line
#
#

log $log_debug "Parse command line: $*"

while [ $# -gt 0 ]
do
    log $log_verbose "Parsing $1"

    case $1 in

	-g | --gatekeeperIdentifier )
	    assert [ $# -gt 1 ]
	    shift; gatekeeper_identifier=$1
	    log $log_debug "--gatekeeperIdentifier set"
	;;

	-b | --backgroundImage )
	    assert [ $# -gt 1 ]
	    shift; background_image=$1
	    log $log_debug "--backgroundImage set"
	;;

	-p | --brandImage )
	    assert [ $# -gt 1 ]
	    shift; brand_image=$1
	    log $log_debug "--brandImage set"
	;;

	-n | --brandName )
	    assert [ $# -gt 1 ]
	    shift; brand_name=$1
	    log "--brandName set"
	;;

	-l | --brankLink )
	    assert [ $# -gt 1 ]
	    shift; brand_link=$1
	    log "--brandLink set"
	;;

	-c | --calls )
	    calls=1
	    log "--calls set"
	;;

	-r | --registrations )
	    calls=0
	    log "--registrations set"
	;;

    	-C | --cisco )
	    background_image="$image_dir/crumpled.jpg"
	    brand_image="$image_dir/cisco.gif"
	    brand_name="Cisco"
	    brand_link="http://www.cisco.com"
    	;;

    	-u | --unknown )
	    unknown_ept=1
	    log "--unknown set"
	;;
			
    	* )
	    log "Unknown option: $1"
	    assert [ false ]
	;;
    esac
    shift
done


#
#   Update gatekeeper identifier
#
#	Use the gatekeeper identifier passed in, otherwise use the
#	name of the directory two up for registration (../..) or 
#	three up (../../..) for calls.
#

gatekeeper_dir="../.."

if [ $calls -gt 0 ]; then
    gatekeeper_dir="../../.."
fi

log "gk_dir:  $gatekeeper_dir"

if [ "$gatekeeper_identifier" = "" ]; then
    gatekeeper_identifier=$(cd $gatekeeper_dir && echo $PWD)
    gatekeeper_identifier=$(basename $gatekeeper_identifier)
fi


#
#   Endpoint identifier variable
#
#	Use the name of the parent directory for registrations or
#	the directory two up (../..) for calls.
#

endpoint_dir=".."

if [ $calls -gt 0 ]; then
    endpoint_dir="../.."
fi

log "ept_dir: $endpoint_dir"

endpoint_identifier=$(cd $endpoint_dir && echo $PWD)
endpoint_identifier=$(basename $endpoint_identifier)

log $log_info "gatekeeper_identifier: $gatekeeper_identifier"
log $log_info "endpoint_identifier:   $endpoint_identifier"
log $log_info "background_image:      $background_image"
log $log_info "brand_image:           $brand_image"
log $log_info "brand_name:            $brand_name"
log $log_info "brand_link:            $brand_link"
log $log_info "calls:                 $calls"

#
#   Find Phone Number
#

phone_number_file="phone_number"
phone_number="unknown"

if [ $calls -eq 0 ]; then

    first_rrq=$($ls -1 *RRQ* *URQ* 2>/dev/null | $head -1 )

    if [ -n "$first_rrq" ]; then

    	phone_number=$(getPhoneNumber $($cat $first_rrq | $egrep "e164" | $head -1))

	$print $phone_number > $phone_number_file
		
    	log $log_info "phone number:          $phone_number"
    fi
fi

#
#   Find call direction
#

sip_to_h323="SIP to H.323"
h323_to_sip="H.323 to SIP"
direction_file="direction"
direction="unknown"

if [ $calls -gt 0 ]; then
    
    first_file=$($ls -1 *.SIP *.H323 2>/dev/null | $head -1 )
    
    $print "$first_file" | $egrep "from.H323" > /dev/null
    
    if [ $? -eq 0 ]; then
    	direction="$h323_to_sip"
    elif [ $? -eq 1 ]; then
        direction="$sip_to_h323"
    fi

    $print $direction > $direction_file

    log $log_info "direction:             $direction"
fi

#
#   Find the Called/Calling Numbers
#

if [ $calls -gt 0 ]; then

    called="unknown"
    calling="unknown"
    called_file="called"
    calling_file="calling"

    phone_1=""
    phone_2=""
        
    setup_file=$($ls -1 *setup* 2>/dev/null | $head -1)
    
    if [ -n "$setup_file" ]; then
    
	setup_e164_count=$($egrep "e164" $setup_file | $wc -l)
	setup_addr_count=$($egrep "sourceAddress|destinationAddress" $setup_file | wc -l)

	if [ $setup_e164_count -eq 2 -a \( $setup_addr_count -eq 2 \) ]; then

    	    phone_1=$(getPhoneNumber $($egrep "e164" $setup_file | $head -1))
    	    phone_2=$(getPhoneNumber $($egrep "e164" $setup_file | $tail -1))

    	    $egrep "sourceAddress|destinationAddress" $setup_file | $head -1 | $egrep "sourceAddress" > /dev/null
	       
	    if [ $? -eq 0 ]; then
        	called="$phone_2"
		calling="$phone_1"
	    elif [ $? -eq 1 ]; then
    		called="$phone_1"
		calling="$phone_2"
	    fi
	    
	else
    	    
    	    arq_file=$($ls -1 *ARQ* 2>/dev/null | $head -1)
    
    	    if [ -n "$arq_file" ]; then
    
		arq_e164_count=$($egrep "e164" $arq_file | $wc -l)
		arq_addr_count=$($egrep "srcInfo|destinationInfo" $arq_file | $wc -l)

		if [ $arq_e164_count -eq 2 -a \( $arq_addr_count -eq 2 \) ]; then

    		    phone_1=$(getPhoneNumber $($egrep "e164" $arq_file | $head -1))
    		    phone_2=$(getPhoneNumber $($egrep "e164" $arq_file | $tail -1))

    		    $egrep "srcInfo|destinationInfo" $arq_file | $head -1 | $egrep "srcInfo" > /dev/null

		    if [ $? -eq 0 ]; then
        		called="$phone_2"
			calling="$phone_1"
		    elif [ $? -eq 1 ]; then
    		    	called="$phone_1"
    		    	calling="$phone_2"
		    fi
		fi
	    fi
	fi
    fi
    
    $print $called > $called_file
    $print $calling > $calling_file
    
    log $log_info "called:                $called"
    log $log_info "calling:               $calling"

    if [ "$direction" = "$sip_to_h323" ]; then
	phone_number="$called"
    else
	phone_number="$calling"
    fi	    

    if [ $unknown_ept -gt 0 ]; then
	$print $phone_number > $phone_number_file
    fi

    log $log_info "phone number:          $phone_number"
fi


#
#   Files
#
#

files=$($ls -1 *.SIP *.H323 2>/dev/null)

log $log_info "files"
for i in $files
do
    log $log_info "\t$(getProtocol $i), $(getMsgType $i), $(getDirection $i), $(getTime $i)"
done

#
#   Start time variable
#
#		

start_date="000000"
start_time="000000"
start_msec="000"
start_file="start_time"

first_file=$($ls -1 *.SIP *.H323 2>/dev/null | $head -1)

start_date=${first_file%%-*}
first_file=${first_file#*-}

start_time=${first_file%%.*}
first_file=${first_file#*.}

start_msec=${first_file%%.*}
	
time_started="$start_date-$start_time.$start_msec"

log $log_info "time started:          $time_started"

$print "$time_started" > $start_file


#
#   End time variable
#
#		

end_date="000000"
end_time="000000"
end_msec="000"
end_file="end_time"

last_file=$($ls -1 *.SIP *.H323 2>/dev/null | $tail -1)

end_date=${last_file%%-*}
last_file=${last_file#*-}

end_time=${last_file%%.*}
last_file=${last_file#*.}

end_msec=${last_file%%.*}
	
time_ended="$end_date-$end_time.$end_msec"

log $log_info "time_ended:            $time_ended"

$print "$time_ended" > $end_file

#
#   Number of total rows in the fence post diagram
#

num_rows=$($ls -1 *.SIP *.H323 2>/dev/null | $wc -l)
let "num_rows = ($num_rows * 2) + 2"

log $log_info "num_rows:              $num_rows"

#
#   Title variables
#
#   	Uses the gatekeeper_identifier, endpoint_idnetifier and the start_time.
#

title="CallTrace: Gatekeeper: $gatekeeper_identifier, Phone Number: $phone_number"

log $log_info "title:                 $title"

title_html="
${content_indent}<h3>
${content_indent_2}Gatekeeper: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  $gatekeeper_identifier,<br>
${content_indent_2}Phone Number:   &nbsp;&nbsp; $phone_number,<br>
${content_indent_2}Time Started: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $time_started,<br>
${content_indent_2}Time Ended:  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $time_ended<br>
${content_indent}</h3>"


#
#   Columns html
#
#   	To create a white column, or a black column for the fence posts.
#

white_column=$(blank_column $num_rows)
black_column=$(blank_column $num_rows \#000000)

#
#   Fence titles html
#
#   	Titles that sit ontop of each fencepost.
#

fence_titles="
$table_begin
$row_begin
$(cell_begin 33 0 0 left bottom) <strong>H.323</strong> $cell_end
$(cell_begin 33 0 0 center bottom) <strong>siph323csgw</strong> $cell_end
$(cell_begin 33 0 0 right bottom) <strong>SIP</strong> $cell_end
$row_end
$table_end
"

#
#   Fence cap html
#
#   	Creates the fence posts
#

fence_cap="
$row_begin
$white_column\n $black_column 
$cell\n $cell\n $cell
$black_column
$cell\n $cell\n $cell
$black_column\n $white_column
$row_end
"

#
#   Blank rail
#
#

blank_rail="
$cell
$cell_46_begin &nbsp; $cell_end
$cell
"

#
#   Rail name
#
#		

function 	rail_name()
{
    assert [ $# -eq 3 ]

    log $log_verbose "rail_name: $*"

    local file=$1
    local msgType=$2
    local time_=$3

    local rc="
$cell
$cell_46_begin
${content_indent}<a href=\"$file\">
${content_indent_2} $msgType $space $time_</a>
${cell_indent}$cell_end
$cell\n"

    log "$rc"

    $print "$rc"
}

#
#   Left pointing rail
#
#

function 	left_rail()
{
    assert [ $# -eq 1 ]

    log $log_verbose "left_rail: $*"

    local file=$1

    local rc="
$cell_01_begin
${content_indent}<a href=\"$file\">
${content_indent_2}<img src=\"$image_dir/left.gif\" height=\"10\" width=\"100%\" border=\"0\"></a>
${cell_indent}$cell_end
$cell_46_begin
${content_indent}<a href=\"$file\">
${content_indent_2}<img src=\"$image_dir/hline.gif\" height=\"10\" width=\"100%\" border=\"0\"></a>
${cell_indent}$cell_end
$cell\n"

    log $log_verbose "returns: $rc"

    $print "$rc"
}

#
#   Right pointing rail
#
#

function	right_rail()
{
    assert [ $# -eq 1 ]

    log $log_verbose "right_rail: $*"

    local file=$1

    local rc="
$cell
$cell_46_begin
${content_indent}<a href=\"$file\">
${content_indent_2}<img src=\"$image_dir/hline.gif\" height=\"10\" width=\"100%\" border=\"0\"></a>
${cell_indent}$cell_end
$cell_01_begin
${content_indent}<a href=\"$file\">
${content_indent_2}<img src=\"$image_dir/right.gif\" height=\"10\" width=\"100%\" border=\"0\"></a>
${cell_indent}$cell_end\n"

    log $log_verbose "returns: $rc"

    $print "$rc"
}		


#
#   Directed rail
#
#

function	directed_rail()
{
    assert [ $# -eq 3 ]

    log $log_verbose "directed_rail: $*"

    local file=$1
    local direction=$2
    local protocol=$3

    local rc=""
    if   [ "$protocol" = "SIP" -a "$direction" = "to" ]; then
	
    	rc="$(right_rail $file)"

    elif [ "$protocol" = "SIP" -a "$direction" = "from" ]; then

    	rc="$(left_rail $file)"

    elif [ "$protocol" = "H323" -a "$direction" = "to" ]; then

    	rc="$(left_rail $file)"
	
    else

    	rc="$(right_rail $file)"

    fi

    log $log_verbose "returns: $rc"

    $print "$rc"
}


#####################################

# Generate the html
#

$print "$(html_start) $(brand_information)"


# Top of the fence
#

$print "$fence_titles "
$print "$table_begin \n$fence_cap"

# Rows

for i in $files
do
    protocol=$(getProtocol $i)
    msg_type=$(getMsgType $i)
    direction=$(getDirection $i)
    time_=$(getTime $i)	

    if [ "$protocol" = "H323" ]; then
	$print "$row_begin $(rail_name $i $msg_type $time_)\n $blank_rail $row_end\n"
	$print "$row_begin $(directed_rail $i $direction $protocol)\n $blank_rail $row_end\n"
    else
	$print "$row_begin $blank_rail $(rail_name $i $msg_type $time_)\n $row_end\n"
	$print "$row_begin $blank_rail $(directed_rail $i $direction $protocol)\n $row_end\n"
    fi
done	

# Bottom of the fence
#
$print "$row_begin $blank_rail $blank_rail $row_end\n"
$print "$(blank_row 11)\n$table_end \n"

$print "$html_end"

