#
# Module: Vyatta::Siproxd.pm
# 
# **** License ****
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# 
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# This code was originally developed by Managed I.T.
# Portions created by Managed I.T. are Copyright (C) 2010 Managed I.T.
# All Rights Reserved.
# 
# Author: Kiall Mac Innes
# Date: May 2010
# Description: Common Siproxd definitions/funcitions
# 
# **** End License ****
#
package Vyatta::Siproxd;
use strict;
use warnings;

our @EXPORT = qw(
    start_daemon
    restart_daemon
    stop_daemon
    is_running
    siproxd_write_file
    siproxd_generate_config
);
use base qw(Exporter);
use File::Basename;
use File::Compare;
use POSIX;

use Vyatta::Config;

my $daemon = '/usr/sbin/siproxd';

sub is_running {
    my ($pid_file) = @_;

    if (-f $pid_file) {
        my $pid = `cat $pid_file`;
        $pid =~ s/\s+$//;  # chomp doesn't remove nl
        my $ps = `ps -p $pid -o comm=`;

        if (defined($ps) && $ps ne "") {
            return $pid;
        }
    }
    return 0;
}

sub start_daemon {
    my ($interface) = @_;

    my $conf_file = "/etc/siproxd-$interface.conf";
    my $pid_file = "/var/run/siproxd/$interface.pid";

    print "Starting siproxd\n";
    my $cmd  = "$daemon -c $conf_file -p $pid_file &> /dev/null";
    system($cmd);
}

sub stop_daemon {
    my ($interface) = @_;
    my $pid_file = "/var/run/siproxd/$interface.pid";

    my $pid      = is_running($pid_file);
    if ($pid != 0) {
        print "Stopping siproxd\n";
        system("kill -INT $pid");
    }
}

sub restart_daemon {
    my ($interface) = @_;

    my $conf_file = "/etc/siproxd-$interface.conf";
    my $pid_file = "/var/run/siproxd/$interface.pid";

    my $pid      = is_running($pid_file);
    if ($pid != 0) {
    system("kill -INT $pid");
    print "Stopping siproxd\n";
    sleep 5; # give the daemon a chance to properly shutdown
    } 
    start_daemon($interface);
}

sub is_same_as_file {
    my ($file, $value) = @_;

    return if ! -e $file;

    my $mem_file = '';
    open my $MF, '+<', \$mem_file or die "couldn't open memfile $!\n";
    print $MF $value;
    seek($MF, 0, 0);
    
    my $rc = compare($file, $MF);
    return 1 if $rc == 0;
    return;
}

sub siproxd_write_file {
    my ($file, $config) = @_;

    # Avoid unnecessary writes.  At boot the file will be the
    # regenerated with the same content.
    return if is_same_as_file($file, $config);

    open(my $fh, '>', $file) || die "Couldn't open $file - $!";
    print $fh $config;
    close $fh;
    return 1;
}

sub check_duplicate_sip_listen_port
{
    #TODO: Ensure each instance of siproxd has a unique sip_listen_port
    
    return 0;
}

sub check_duplicate_sip_rtp_port
{
    #TODO: Ensure each instance of siproxd has a unique rtp_port range

    return 0;
}

sub siproxd_generate_config {
    my ($interface) = @_;

    if (check_duplicate_sip_listen_port() == 1) {
    print "Duplicate siproxd-port\n";
        exit 1;
    }

    if (check_duplicate_sip_rtp_port() == 1) {
    print "Duplicate rtp-port\n";
        exit 1;
    }

    my $config = new Vyatta::Config;
    $config->setLevel("service sip-proxy listen-on $interface");

    my $outbound_interface = $config->returnValue('outbound-interface');
    my $listen_port = $config->returnValue('listen-port');
    my $siproxd_port = $config->returnValue("siproxd-port");
    my ($rtp_port_low, $rtp_port_high) = split(/-/, $config->returnValue("rtp-port"));

    my $output = '# autogenerated by siproxd-config.pl' ."\n#\n";
    $output .= "if_inbound  = $interface\n";
    $output .= "if_outbound = $outbound_interface\n";
    $output .= "sip_listen_port = $siproxd_port\n";
    $output .= "daemonize = 1\n";
    $output .= "silence_log = 0\n";
    $output .= "user = siproxd\n";
    $output .= "registration_file = /var/lib/siproxd/siproxd_registrations_$interface\n";
    $output .= "autosave_registrations = 300\n";
    $output .= "rtp_proxy_enable = 1\n";
    $output .= "rtp_port_low  = $rtp_port_low\n";
    $output .= "rtp_port_high = $rtp_port_high\n";
    $output .= "rtp_timeout = 300\n";
    $output .= "rtp_dscp = 46\n";
    $output .= "rtp_input_dejitter  = 100000\n";
    $output .= "rtp_output_dejitter = 100000\n";
    $output .= "default_expires = 600\n";
    $output .= "debug_level = 0x00000000\n";
    $output .= "debug_port = 0\n";
    $output .= "plugindir=/usr/lib/siproxd/\n";
    $output .= "load_plugin=plugin_logcall.so\n";
    $output .= "load_plugin=plugin_stun.so\n";
    $output .= "plugin_stun_server = stun.ekiga.net\n";
    $output .= "plugin_stun_port = 3478\n";
    $output .= "plugin_stun_period = 300\n";

    return siproxd_write_file("/etc/siproxd-$interface.conf", $output);
}


1;
#
