Perl中的Net :: SMPP,如何从我的ESME向SMSC发送确认

时间:2013-01-01 05:00:23

标签: perl sms smpp

我正在写一个Perl脚本,它将充当接收器和放大器。使用Net :: SMPP的发射机。当移动用户将消息发送到短代码(比如123)时,它将到达我的SMPP帐户,我的SMPP应用程序将读取该消息并回复并向用户发送确认,例如“谢谢您发送消息” ”。 我收到用户发送到我的SMPP应用程序的消息完全没问题。问题是将确认(delivery_sm_resp)发送回SMSC,以便从流中删除该消息,以便可以收集其他用户发送的下一条消息。我尝试使用该功能,但我无法弄清楚从SMSC收到的消息到我的ESME的message_id。

我的代码是。

my $transmitter = Net::SMPP->new_transmitter($host,port=> $port,system_id => '123',password  => '',) or die;

$receiver = Net::SMPP->new_receiver($host,system_id => '123',password => '',port => $port,)
    or die "Can't create server: $!";

while (1) {
    warn "Waiting for PDU";
    $pdu = $receiver->read_pdu() or die "$$: PDU not read. Closing connection";
    print "Received #$pdu->{seq} $pdu->{cmd}:". Net::SMPP::pdu_tab->{$pdu->{cmd}}{cmd} ."\n";
    warn Dumper($pdu);

    print "\n\n ** Hello ** " . $pdu->{message_id} . "\n ** now printing ** " . $pdu->{sm_default_msg_id};
    $transmitter->deliver_sm_resp( message_id => $pdu->{sm_default_msg_id}, seq => $pdu->{seq});
    $resp_pdu = $transmitter->submit_sm(
        destination_addr => $pdu->{source_addr},
        short_message    => "you sent a message with text " . $pdu->{short_message}
    ) or die "Response indicated error: " . $resp_pdu->explain_status();

}

我从SMSC收到的消息显示给我的ESME如下。请帮助我找到它的message_id,它可用于确认SMSC,以便从流中删除该消息,并可以接受其他用户发送的下一条消息。否则我会收到相同的PDU 3次,直到超时,下一条消息无法接受。

Waiting for PDU at s.pl line 23.
Received #2 5:deliver_sm
$VAR1 = bless( {
             'source_addr_ton' => 1,
             'known_pdu' => 1,
             'schedule_delivery_time' => '',
             'protocol_id' => 0,
             'status' => 0,
             'short_message' => 'A',
             'dest_addr_npi' => 0,
             'source_addr' => '44702601843',
             'validity_period' => '',
             'registered_delivery' => 0,
             'dest_addr_ton' => 0,
             'seq' => 2,
             'data_coding' => 1,
             'service_type' => '',
             'replace_if_present_flag' => 0,
             'cmd' => 5,
             'priority_flag' => 0,
             'data' => '44702601843420A',
             'destination_addr' => '420',
             'esm_class' => 0,
             'sm_default_msg_id' => 0,
             'source_addr_npi' => 0,
             'reserved' => undef
           }, 'Net::SMPP::PDU' );

2 个答案:

答案 0 :(得分:3)

答案: 我正在检查更多,并发现从ESME发送确认响应 - > SMSC应在代码中使用以下命令。我希望有时可以帮助别人。 :)

$receiver->data_sm_resp(message_id => $pdu->{sm_default_msg_id}, seq => $pdu->{seq});

答案 1 :(得分:0)

附件是允许我接收短信的代码

#!/usr/bin/perl
#
# Copyright (c) 2001 SymLABS <symlabs@symlabs.com>, All Rights Reserved.
# See README for license. NO WARRANTY.
#
# 10.7.2001, Sampo Kellomaki <sampo@symlabs.com>
# $Id: esme-rec.pl,v 1.4 2002/02/11 16:43:47 sampo Exp $
#
# ESME in receiver role.
#
# Test Net::SMPP in SMSC role
#
# Usage: ./esme-rec.pl *version*
#    version can be 4 or 3             #4

use Net::SMPP;
use Data::Dumper;

$trace = 1;
$sysid = "username";
$pw = "password";
$host = 'ip address';
$port = port;
$facil = 0x00010003;
($vers) = @ARGV;
$vers = $vers == 4 ? 0x40 : 0x34;   #4
$if_vers = 0x00;

use constant reply_tab => {
    0x80000000 => { cmd => 'generic_nack', reply => undef, },
    0x00000001 => { cmd => 'bind_receiver',
            reply => sub { my ($me,$pdu) = @_;
                   $me->set_version(0x34);
                   $me->bind_receiver_resp(system_id => $sysid,
                               seq => $pdu->{seq});
                       }, },
    0x80000001 => { cmd => 'bind_receiver_resp', reply => undef, }, 
    0x00000002 => { cmd => 'bind_transmitter',
            reply => sub { my ($me, $pdu) = @_;
                   $me->set_version(0x34);
                   warn "Doing bind_tx_resp";
                   $me->bind_transmitter_resp(system_id => $sysid,
                               seq => $pdu->{seq});
                   }, },
    0x80000002 => { cmd => 'bind_transmitter_resp', reply => undef, }, 
    0x00000003 => { cmd => 'query_sm',
            reply => sub { my ($me, $pdu) = @_;
                   $me->query_sm_resp(message_id=>$pdu->{message_id},
                              final_date=>'010711135959000+',
                               seq => $pdu->{seq},
                              ) }, },
    0x80000003 => { cmd => 'query_sm_resp', reply => undef, },     
    0x00000004 => { cmd => 'submit_sm',
            reply => sub { my ($me, $pdu) = @_;
                   $me->submit_sm_resp(message_id=>'123456789',
                               seq => $pdu->{seq}) }, },
    0x80000004 => { cmd => 'submit_sm_resp', reply => undef, },   
    0x00000005 => { cmd => 'deliver_sm', reply => undef, },    # we originate this
    0x80000005 => { cmd => 'deliver_sm_resp', reply => undef, },  # *** need to handle this?
    0x00000006 => { cmd => 'unbind',
            reply => sub { my ($me, $pdu) = @_;
                   $me->unbind_resp(seq => $pdu->{seq});
                   warn "$$: Remote sent unbind. Dropping connection.";
                   exit;
                   }, },       
    0x80000006 => { cmd => 'unbind_resp',
            reply => sub { warn "$$: Remote replied to unbind. Dropping connection.";
                   exit;
                   }, },
    0x00000007 => { cmd => 'replace_sm',
            reply => sub { my ($me, $pdu) = @_;
                   $me->replace_sm_resp(seq => $pdu->{seq}) }, },
    0x80000007 => { cmd => 'replace_sm_resp', reply => undef, }, 
    0x00000008 => { cmd => 'cancel_sm', reply => sub { my ($me, $pdu) = @_;
                           $me->cancel_resp(seq => $pdu->{seq}) }, },
    0x80000008 => { cmd => 'cancel_sm_resp', reply => undef, },  
    0x00000009 => { cmd => 'bind_transceiver',
            reply => sub { my ($me, $pdu) = @_;
                   $me->set_version(0x34);
                   $me->bind_transceiver_resp(system_id => $sysid,
                                  seq => $pdu->{seq});
                   }, },
    0x80000009 => { cmd => 'bind_transceiver_resp', reply => undef, }, 
    0x0000000b => { cmd => 'outbind',
            reply => sub {  my ($me, $pdu) = @_;
                    $me->set_version(0x34);
                    $me->bind_receiver(system_id => $sysid,
                               password => $pw) }, },
    0x00000015 => { cmd => 'enquire_link',
            reply => sub { my ($me, $pdu) = @_;
                   $me->enquire_link_resp(seq => $pdu->{seq}) }, },      
    0x80000015 => { cmd => 'enquire_link_resp', reply => undef, }, 
    0x00000021 => { cmd => 'submit_multi',
            reply => sub { my ($me, $pdu) = @_;
                   $me->submit_multi_resp(message_id=>'123456789',
#                                 no_unsuccess=>0,
                              seq => $pdu->{seq} ) }, },
    0x80000021 => { cmd => 'submit_multi_resp', reply => undef, }, 
    0x00000102 => { cmd => 'alert_notification', reply => undef, },  # ***
    0x00000103 => { cmd => 'data_sm', reply => undef, },  # ***
    0x80000103 => { cmd => 'data_sm_resp', reply => undef, }, 

#4#cut

    # v4 codes

    0x80010000 => { cmd => 'generic_nack_v4', reply => undef, }, 
    0x00010001 => { cmd => 'bind_receiver_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->set_version(0x40);
                   $me->bind_receiver_resp(system_id => $sysid,
                               facilities_mask => $facil,
                               seq => $pdu->{seq});
                   }, },
    0x80010001 => { cmd => 'bind_receiver_resp_v4', reply => undef, }, 
    0x00010002 => { cmd => 'bind_transmitter_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->set_version(0x40);
                   $me->bind_transmitter_resp(system_id => $sysid,
                                  facilities_mask =>  $facil,
                                  seq => $pdu->{seq});
                   }, },
    0x80010002 => { cmd => 'bind_transmitter_resp_v4', reply => undef, }, 
    0x00010003 => { cmd => 'query_sm_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->query_sm_resp(message_id=>$pdu->{message_id},
                              final_date=>'010711135959000+',
                              seq => $pdu->{seq}) }, },
    0x80010003 => { cmd => 'query_sm_resp_v4', reply => undef, },     
    0x00010004 => { cmd => 'submit_sm_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->submit_sm_resp(message_id=>'123456789',
#                                  num_unsuccess=>0,
#                                  destination_addr=>$pdu->      {source_addr},
                               error_status_code => 0,
                               seq => $pdu->{seq} ) }, },
    0x80010004 => { cmd => 'submit_sm_resp_v4', reply => undef, },   
    0x00010005 => { cmd => 'deliver_sm_v4', reply => undef, },
    0x80010005 => { cmd => 'deliver_sm_resp_v4', reply => undef, },  # Need to handle this?
    0x00010006 => { cmd => 'unbind_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->unbind_resp(seq => $pdu->{seq});
                   warn "$$: Remote sent unbind. Dropping connection.";
                   exit;
                   }, },       
    0x80010006 => { cmd => 'unbind_resp_v4',
            reply => sub { warn "$$: Remote replied to unbind. Dropping connection.";
                   exit;
                   }, },       
    0x00010007 => { cmd => 'replace_sm_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->replace_sm_resp(seq => $pdu->{seq}) }, },
    0x80010007 => { cmd => 'replace_sm_resp_v4', reply => undef, }, 
    0x00010008 => { cmd => 'cancel_sm_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->cancel_resp(seq => $pdu->{seq}) }, },      
    0x80010008 => { cmd => 'cancel_sm_resp_v4', reply => undef, },  
    0x00010009 => { cmd => 'delivery_receipt_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->delivery_receipt_resp(seq => $pdu->{seq}) }, },
    0x80010009 => { cmd => 'delivery_receipt_resp_v4', reply => undef, },  
    0x0001000a => { cmd => 'enquire_link_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->enquire_link_resp(seq => $pdu->{seq}) }, },
    0x8001000a => { cmd => 'enquire_link_resp_v4', reply => undef, },
    0x0001000b => { cmd => 'outbind_v4',
            reply => sub { my ($me, $pdu) = @_;
                   $me->set_version(0x34);
                   $me->bind_receiver(system_id => $sysid,
                              password => $pw,
                              facilities_mask => $facil,
                              seq => $pdu->{seq}) }, },
#4#end
};

($smpp, $resp) = Net::SMPP->new_transceiver($host,
                  smpp_version => $vers,
                  interface_version => $if_vers,
                  system_id => $sysid,
                  password => $pw,
                  addr_ton => 0x01,
                  addr_npi => 0x01,
                  source_addr_ton => 0x01,
                  source_addr_npi => 0x01,
                  dest_addr_ton => 0x01,
                  dest_addr_npi => 0x01,
                  system_type => '',
                  facilities_mask => $facil,
                  port => $port,
#               timeout => 7,
                  )
    or die "Can't create server: $!";

warn Dumper $resp;

print "#### Connected: ###### \n smpp:$smpp, \n resp:$resp";


while (1) {
 warn "Waiting for PDU";
 $pdu = $smpp->read_pdu() or { $bind_fail = "yes" };

Net::SMPP::Pdu_tab->{$pdu->{cmd}}{cmd} ."\n";

### read in data
 $short_message = $pdu->{short_message};
 $source_addr = $pdu->{source_addr};
 $seq = $pdu->{seq};

print "\n ===> Bind failed=$bind_fail \n";

########### if bind failed above - try to reconnect
 if ($bind_fail eq "yes"){
 print "\n Reconnecting \n";
 ($smpp, $resp) = Net::SMPP->new_transceiver($host,
 smpp_version => $vers,
 interface_version => $if_vers,
 system_id => $sysid,
 password => $pw,
 addr_ton => 0x00,
 addr_npi => 0x01,
 source_addr_ton => 0x0,
 source_addr_npi => 0x1,
 dest_addr_ton => 0x0,
 dest_addr_npi => 0x1,
 system_type => '',
 facilities_mask => $facil,
 port => $port,
 # timeout => 7,
 )
 or die "Can't create server: $!";
 sleep 2;
 }#fi bind_fail

warn Dumper($pdu) if $trace;
 $mh_msg_id = "$pdu->{seq}";

 if (defined reply_tab->{$pdu->{cmd}}) {
 $smpp->deliver_sm_resp(message_id => $mh_msg_id, seq => $mh_msg_id) or die; ### we use pdu->    {seq} as message_id, as we cannot find message_id, fix later

warn "Replied";

} else {
 warn "Don't know to reply to $pdu->{cmd}";
 sleep 1;
 }
 }


#EOF