#!/usr/bin/perl -w
#---------------------------------------------------------------------
# gsgsmppin
# Alamin GSM SMS Gateway SMPP input interface
#---------------------------------------------------------------------
# (C) Andrs Seco Hernndez, April 2000-Oct 2004
#
# 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.
#
# 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.
#
#---------------------------------------------------------------------

=pod

=head1 NAME

gsgsmppin - Alamin GSM SMS Gateway SMPP input interface

=head1 SYNOPSIS

gsgsmppin [-c config_file_name]

=head1 DESCRIPTION

gsgsmppin is the component that retrieves messages queued into a SMSC with a
SMPP interface, to be passed to the gsgimp defined. Connect parameters are
configured using its config file.

=head1 OPTIONS

=over

=item -c <file_name>

(default: /etc/alamin/gsgsmppin.conf) Sets the config file to be used. It is a perl formated file, be careful with the perl syntax.

=back

=head1 FILES

/etc/alamin/gsgsmppin.conf

=head1 SEE ALSO

See also gsgc(1), gsgcmd(8), gsgmdd(8), gsgsmppin(8), gsgsmppout(8) and
gsgdb2sms(8).

=head1 BUGS

Send bugs to the author, please. I would like to keep the program without
bugs.

=head1 LICENSE

Alamin GSM SMS Gateway
Copyright (C) Andres Seco Hernandez and others.

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.

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.

=head1 AUTHOR

Andres Seco Hernandez <AndresSH@alamin.org>.

=cut

use strict;

my $timetoterminate = 0;
$SIG{TERM} = \&TERMINATE;

use Sys::Syslog qw(:DEFAULT setlogsock);
use Getopt::Std;
use Net::SMPP;
use Date::Format;

my $program_name = "gsgsmppin";
my $program_version = "v0.3.7 - Oct 25, 2004";

my $waittime = 1;
my $verbose = 1;
my $debug = 1;
my $usesyslog = 1;
my $syslogfacility = "local0";
my $pidfile = "/var/run/alamin/gsgsmppin.pid";
my $runasdaemon = 1;
my $smpphost = 'smpphost';
my $smppport = 1234;
my $smppvers = 0x34;
my $smppuser = "smppuser";
my $smpppass = "smpppass";
my $smppsyst = "smppsyst";
my $smpptout = 30;
my $spoolpath = '/var/spool/alamin/smpp-in';

my %opt;
getopts ("c:", \%opt);
my $configfile = $opt{"c"} || "/etc/alamin/gsgsmppin.conf";
eval `cat $configfile`;

if ($runasdaemon) {
  use Proc::Daemon;
  Proc::Daemon::Init;
}

setlogsock "unix";
openlog($program_name,"pid",$syslogfacility);
umask 007;
open (PIDFILE,">".$pidfile);
print PIDFILE "$$";
close (PIDFILE);
logit("info","Starting Alamin GSM SMS Gateway - $program_name - $program_version") if ($verbose);

my $pdu;
my $smpp;
my $counter = 0;

use constant reply_tab => {
    0x00000005 => { cmd => 'deliver_sm', 
		    reply => sub { my ($me, $pdu) = @_;
				   my $message_id=$smppuser.time2str("%Y%m%d%H%M%S",time).$$.$counter;
				   $counter++;
				   open (MSGFILE,">".$spoolpath."/".$message_id);
				   print MSGFILE "HEADER $message_id $pdu->{source_addr} $pdu->{service_type}\n";
				   print MSGFILE "BODYSTART\n";
				   print MSGFILE "$pdu->{short_message}\n";
				   print MSGFILE "BODYEND\n";
				   close (MSGFILE);
                                   logit("info","Received smpp pdu command $pdu->{cmd} from $pdu->{source_addr}.") if ($verbose);
				   $me->deliver_sm_resp(message_id=>$message_id,
				                        seq => $pdu->{seq}) }, },
};

while(!$timetoterminate) {
  eval {
    $smpp = Net::SMPP->new_receiver($smpphost, port => $smppport,
                                    smpp_version => $smppvers, timeout => $smpptout,
                                    system_id => $smppuser, password => $smpppass,
                                    system_type => $smppsyst);
  };
  if (!$@ && $smpp) {
    my $connected = 1;
    while ($connected) {
      eval {
        $pdu = $smpp->read_pdu();
      };
      if (!$@ && $pdu) {
        if (defined reply_tab->{$pdu->{cmd}}) {
          &{reply_tab->{$pdu->{cmd}}{reply}}($smpp, $pdu);
        } else {
          logit("warning","Received smpp pdu command $pdu->{cmd}, no response for it.") if ($verbose);
        }
      } else {
        $connected = 0;
      }
      logit("debug","Waiting $waittime seconds.") if ($debug);
      sleep $waittime;
    }
  }
  my $rewaittime = $waittime * 2;
  logit("warning","Lose SMPP connection, reconnecting in $rewaittime seconds.") if ($verbose);
  sleep $rewaittime;
}

logit("info","Exiting.") if ($verbose);
unlink $pidfile;
closelog;

if ($smpp) {
  $smpp->unbind();
}

sub TERMINATE {
  $timetoterminate = 1;
  logit("debug","SIGTERM received, ending tasks...") if ($debug);
}

sub logit {
  my ($log_type, $log_message) = @_;
  if ($usesyslog) {
    syslog($log_type,$log_message);
  }
}
