Sunday, October 23, 2011

Net::UCP::Client SMSC Protocol in PERL

This post will teach you how to create an SMSC UCP client in Perl.

1. First, you will need Perl libraries that needs to be installed in your server. Libraries are as follows:
  • POSIX
  • Time::HiRes
  • File::Copy
  • Encode
  • Net::UCP
  • Data::Dumper
2. Initialize the script by creating SMSC object passing the smsc ip, smsc port, and smsc profile.

my $emi = Net::UCP->new (
        SMSC_HOST   => $smsc_ip,
        SMSC_PORT   => $smsc_port,
        SENDER_TEXT => $profile,
        SRC_HOST    => $source_ip,            # optional
        SRC_PORT    => $source_port,          # optional
        WARN        => 1,

        FAKE        => 0
) or die("Failed to create SMSC object");

$emi->open_link() or die($!);

3. Login to SMSC by supplying smsc id, smsc password, and smsc access code.

my ($acknowledge, $error_number, $error_text) = $emi->login(
        SMSC_ID    => $smsc_id,
        SMSC_PW    => $smsc_pw,
        SHORT_CODE => $smsc_ac,
        OTON       => $ton,       # optional
        ONPI       => '5',        # optional
        VERS       => '0100',     # optional
);

die ("Login to SMSC failed. Error nbr: $error_number, Error txt: $error_text\n") unless($acknowledge);

4. Loop in to fetch SMSC messages. Please take note that we need to have a call-back function to call whenever it reaches timeout. All messages can be parsed by using parse_message() function that will return hash data.

$message = $emi->wait_in_loop(
        timeout => $timeout,
        clear => 1,
        action => \&timedout
);

if (defined($message)) {
        print "wait_in_loop: $message\n";
        $hshmsg = $emi->parse_message($message);

        $chksum = $hshmsg->{checksum};
        $rpid = $hshmsg->{rpid};
        $dcs = $hshmsg->{dcs};
        $type = $hshmsg->{type};
        $len = $hshmsg->{len};
        $xser = $hshmsg->{xser};
        $mt = $hshmsg->{mt};
        $trn = $hshmsg->{trn};
        $ot = $hshmsg->{ot};
        $srcmin = $hshmsg->{oadc};
        $dstmin = $hshmsg->{adc};
        $smsmsg = $hshmsg->{amsg};
        $tstamp = $hshmsg->{scts};
}

sub timedout {
        print "timeout reached...";
        exit 0;
}

5. Lastly, you need to acknowledge the receipt of messages by transmitting back the transaction id from the message you received.

$ucp_string = $emi->make_52(
        result => 1,
        trn => $trn,
        ack => 'A'
);

if ( defined($ucp_string) ) {
        ($acknowledge, $error_number, $error_text) = $emi->transmit_msg( $ucp_string, 10, 0 );
        print "transmit_msg: $error_text\n";
}


Please see below for the complete code with log and dump feature. Hope you like it.

#!/usr/bin/perl

use POSIX qw(strftime);
use Time::HiRes qw(usleep ualarm gettimeofday tv_interval);
use File::Copy;

use Encode;
use Net::UCP;
use Data::Dumper;

my ($message, $tstamp, $srcmin, $dstmin, $type, $xser, $mt, $trn, $ot, $smsmsg, $hshmsg, $ucp_string, $rpid, $chksum, $dcs, $len);

my $timeout = 120; # set timeout when fetching messages in secs

my $ton = 6; # set your TON from the SMSC server.
print "ton: $ton\n";

my $smsc_id = 'xxxx'; # set your SMSC ID
print "smsc id: $smsc_id\n";

my $smsc_pw = 'xxxxxxx'; # set your SMSC Password
print "smsc pw: $smsc_pw\n";

my $smsc_ac = 'xxxx'; # set your SMSC Access Code
print "smsc ac: $smsc_ac\n";

my $smsc_ip = 'xxx.xxx.xxx.xx'; # set the SMSC Destination IP
print "smsc ip: $smsc_ip\n";

my $smsc_port = 'xxxx'; # set the SMSC Destination Port
print "smsc port: $smsc_port\n";

my $source_ip = 'xxx.xxx.xxx.xx'; # set your SMSC Source IP
print "source ip: $source_ip\n";

my $source_port = 'xxxx'; # set your SMSC Source Port
print "source port: $source_port\n";

my $profile = 'xxxx'; # set your profile for logging
print "profile: $profile\n";

my $dumpdir = '/home/your/smsc/ucp/dump/directory'; # set your incoming dump directory
system "mkdir -p $dumpdir" if (!-e $dumpdir);
print "dump dir: $dumpdir\n";

my $logdir = '/home/your/smsc/ucp/log/directory'; # set your incoming log directory
system "mkdir -p $logdir" if (!-e $logdir);
print "log dir: $logdir\n";


# initialization... creating smsc object...
my $emi = Net::UCP->new (
  SMSC_HOST   => $smsc_ip,
  SMSC_PORT   => $smsc_port,
  SENDER_TEXT => $profile,
  SRC_HOST    => $source_ip,            # optional
  SRC_PORT    => $source_port,          # optional
  WARN        => 1,
  FAKE        => 0
) or die("Failed to create SMSC object");

$emi->open_link() or die($!);

# login to smsc...
my ($acknowledge, $error_number, $error_text) = $emi->login(
  SMSC_ID    => $smsc_id,
  SMSC_PW    => $smsc_pw,
  SHORT_CODE => $smsc_ac,
  OTON       => $ton,        # optional
  ONPI       => '5',        # optional
  VERS       => '0100',     # optional
);

die ("Login to SMSC failed. Error nbr: $error_number, Error txt: $error_text\n") unless($acknowledge);


while (1)
{
  # start fetching here..
  $message = $emi->wait_in_loop(
        timeout => $timeout,
        clear   => 1,
        action  => \&timedout
  );

  if (defined($message)) {
        &logme_raw($message);

        print "wait_in_loop: $message\n";
        $hshmsg = $emi->parse_message($message);

        $chksum = $hshmsg->{checksum};
        $rpid   = $hshmsg->{rpid};
        $dcs    = $hshmsg->{dcs};
        $type   = $hshmsg->{type};
        $len    = $hshmsg->{len};
        $xser   = $hshmsg->{xser};
        $mt     = $hshmsg->{mt};
        $trn    = $hshmsg->{trn};
        $ot     = $hshmsg->{ot};
        $srcmin = $hshmsg->{oadc};
        $dstmin = $hshmsg->{adc};
        $smsmsg = $hshmsg->{amsg};
        $tstamp = $hshmsg->{scts};

        &dumpme($profile, $srcmin, $dstmin, $type, $tstamp, $mt, $trn, $ot, $smsmsg);

        $ucp_string = $emi->make_52(
                  result => 1,
                  trn    => $trn,
                  ack    => 'A'
                  );

        if ( defined($ucp_string) ) {
                &logme_raw($ucp_string);

                ($acknowledge, $error_number, $error_text) = $emi->transmit_msg( $ucp_string, 10, 0 );
                print "transmit_msg: $error_text\n";
        }
  }
  else
  {
        print "no message from smsc\n";
  }
}

sub timedout {
  print "timeout reached...";

  exit 0;
}

sub logme
{
  my ($logdata) = @_;
  my ($logdate, $logtime);

  $logdate = strftime "%Y%m%d", localtime();
  $logtime = strftime "%H%M%S", localtime();

  open FLOG, ">> $logdir/$logdate-$profile.log";
  print FLOG "$logdate-$logtime -- $logdata\n";
  close FLOG;

  return 1;
}

sub logme_raw
{
  my ($logdata) = @_;
  my ($logdate, $logtime);

  $logdate = strftime "%Y%m%d", localtime();
  $logtime = strftime "%H%M%S", localtime();

  open FLOG, ">> $logdir/$logdate-$profile.raw";
  print FLOG "$logdate-$logtime -- $logdata\n";
  close FLOG;

  return 1;
}

sub dumpme
{
  my ($profile, $srcmin, $dstmin, $type, $tstamp, $mt, $trn, $ot, $smsmsg) = @_;
  my ($date, $time, $fname, $data);

  $date = strftime "%Y%m%d", localtime();
  $time = strftime "%H%M%S", localtime();

  $fname = "$date.$time.$tstamp";
  $data = "$profile|$srcmin|$dstmin|$type|$xser|$mt|$trn|$ot|$smsmsg";

  print "$data\n";
  &logme($data);

  open FILE, ">> $dumpdir/.$fname";
  print FILE "$data\n";
  close FILE;

  move("$dumpdir/.$fname","$dumpdir/$fname");
  return 1;
}

$emi->close_link();
print "done!";



1;


- Great leaders see the need, seize the opportunity, and serve without expecting anything in return. follow me on twitter @paulgonzaga

2 comments:

  1. hi, good posting..

    May you give example how to retrieve delivery notification(OP 53 type O) which initiated by SMSC?

    Tq

    ReplyDelete
  2. Sorry for the late reply.. please try calling make_53.

    $ucp_string = $emi->make_52(
    result => 1,
    trn => $trn,
    ack => 'A'
    );

    ReplyDelete

Leadership 101


  • Leadership demands sacrifices for the near-term to receive lasting benefits. the longer we wait to make sacrifices, the harder they become. Successful people make important decisions early in their life, then manage those decisions the rest of their lives.
  • Growth does not happen by chance. If you want to be sure to grow, you need a plan something strategic, specific, and scheduled. it's a discipline that would need incredible determination from us.
  • Success comes by going the extra mile, working the extra hours, and investing the extra time. The same is true for us. If we want to get to excel in any segment of life, a little extra effort can help. Our efforts can go a long way if we only work a little smarter, listen a little better, push a little harder, and persevere a little longer.
  • Making a difference in your work is not about productivity; it's about people. When you focus on others and connect with them, you can work together to accomplish great things.
  • Envision a goal you'd like to reach. Make it big enough to scare you a little. Now write down a plan for moving toward it. Create mini-goals within the big goal, to set yourself up for continual progress. And include some risks, too. Set yourself up for success.
  • Leaders build margins, not image. A leader may be forced to take unpopular stands for the good of the company. Popularity isn't bad, but decisions made solely on the basis of popular opinion can be devastating. So take courage and make the right though sometimes painful choices.