1#!/usr/local/bin/perl
2#
3# Copyright (c) 2001 SymLABS <symlabs@symlabs.com>, All Rights Reserved.
4# See README for license. NO WARRANTY.
5#
6# 10.7.2001, Sampo Kellomaki <sampo@symlabs.com>
7# $Id: esme-rec.pl,v 1.4 2002/02/11 16:43:47 sampo Exp $
8#
9# ESME in receiver role.
10#
11# Test Net::SMPP in SMSC role
12#
13# Usage: ./esme-rec.pl *version*
14#    version can be 4 or 3             #4
15
16use Net::SMPP;
17use Data::Dumper;
18
19$trace = 1;
20$sysid = "GSMSGW";
21$pw = "secret";
22$host = 'localhost';
23$port = 9900;
24$facil = 0x00010003;
25($vers) = @ARGV;
26$vers = $vers == 4 ? 0x40 : 0x34;   #4
27$if_vers = 0x00;
28
29use constant reply_tab => {
30    0x80000000 => { cmd => 'generic_nack', reply => undef, },
31    0x00000001 => { cmd => 'bind_receiver',
32		    reply => sub { my ($me,$pdu) = @_;
33				   $me->set_version(0x34);
34				   $me->bind_receiver_resp(system_id => $sysid,
35							   seq => $pdu->{seq});
36			       }, },
37    0x80000001 => { cmd => 'bind_receiver_resp', reply => undef, },
38    0x00000002 => { cmd => 'bind_transmitter',
39		    reply => sub { my ($me, $pdu) = @_;
40				   $me->set_version(0x34);
41				   warn "Doing bind_tx_resp";
42				   $me->bind_transmitter_resp(system_id => $sysid,
43							   seq => $pdu->{seq});
44			       }, },
45    0x80000002 => { cmd => 'bind_transmitter_resp', reply => undef, },
46    0x00000003 => { cmd => 'query_sm',
47		    reply => sub { my ($me, $pdu) = @_;
48				   $me->query_sm_resp(message_id=>$pdu->{message_id},
49						      final_date=>'010711135959000+',
50							   seq => $pdu->{seq},
51						      ) }, },
52    0x80000003 => { cmd => 'query_sm_resp', reply => undef, },
53    0x00000004 => { cmd => 'submit_sm',
54		    reply => sub { my ($me, $pdu) = @_;
55				   $me->submit_sm_resp(message_id=>'123456789',
56						       seq => $pdu->{seq}) }, },
57    0x80000004 => { cmd => 'submit_sm_resp', reply => undef, },
58    0x00000005 => { cmd => 'deliver_sm', reply => undef, },    # we originate this
59    0x80000005 => { cmd => 'deliver_sm_resp', reply => undef, },  # *** need to handle this?
60    0x00000006 => { cmd => 'unbind',
61		    reply => sub { my ($me, $pdu) = @_;
62				   $me->unbind_resp(seq => $pdu->{seq});
63				   warn "$$: Remote sent unbind. Dropping connection.";
64				   exit;
65			       }, },
66    0x80000006 => { cmd => 'unbind_resp',
67		    reply => sub { warn "$$: Remote replied to unbind. Dropping connection.";
68				   exit;
69			       }, },
70    0x00000007 => { cmd => 'replace_sm',
71		    reply => sub { my ($me, $pdu) = @_;
72				   $me->replace_sm_resp(seq => $pdu->{seq}) }, },
73    0x80000007 => { cmd => 'replace_sm_resp', reply => undef, },
74    0x00000008 => { cmd => 'cancel_sm', reply => sub { my ($me, $pdu) = @_;
75						       $me->cancel_resp(seq => $pdu->{seq}) }, },
76    0x80000008 => { cmd => 'cancel_sm_resp', reply => undef, },
77    0x00000009 => { cmd => 'bind_transceiver',
78		    reply => sub { my ($me, $pdu) = @_;
79				   $me->set_version(0x34);
80				   $me->bind_transceiver_resp(system_id => $sysid,
81							      seq => $pdu->{seq});
82			       }, },
83    0x80000009 => { cmd => 'bind_transceiver_resp', reply => undef, },
84    0x0000000b => { cmd => 'outbind',
85		    reply => sub {  my ($me, $pdu) = @_;
86				    $me->set_version(0x34);
87				    $me->bind_receiver(system_id => $sysid,
88						       password => $pw) }, },
89    0x00000015 => { cmd => 'enquire_link',
90		    reply => sub { my ($me, $pdu) = @_;
91				   $me->enquire_link_resp(seq => $pdu->{seq}) }, },
92    0x80000015 => { cmd => 'enquire_link_resp', reply => undef, },
93    0x00000021 => { cmd => 'submit_multi',
94		    reply => sub { my ($me, $pdu) = @_;
95				   $me->submit_multi_resp(message_id=>'123456789',
96#							  no_unsuccess=>0,
97							  seq => $pdu->{seq} ) }, },
98    0x80000021 => { cmd => 'submit_multi_resp', reply => undef, },
99    0x00000102 => { cmd => 'alert_notification', reply => undef, },  # ***
100    0x00000103 => { cmd => 'data_sm', reply => undef, },  # ***
101    0x80000103 => { cmd => 'data_sm_resp', reply => undef, },
102
103#4#cut
104
105    # v4 codes
106
107    0x80010000 => { cmd => 'generic_nack_v4', reply => undef, },
108    0x00010001 => { cmd => 'bind_receiver_v4',
109		    reply => sub { my ($me, $pdu) = @_;
110				   $me->set_version(0x40);
111				   $me->bind_receiver_resp(system_id => $sysid,
112							   facilities_mask => $facil,
113							   seq => $pdu->{seq});
114			       }, },
115    0x80010001 => { cmd => 'bind_receiver_resp_v4', reply => undef, },
116    0x00010002 => { cmd => 'bind_transmitter_v4',
117		    reply => sub { my ($me, $pdu) = @_;
118				   $me->set_version(0x40);
119				   $me->bind_transmitter_resp(system_id => $sysid,
120							      facilities_mask => $facil,
121							      seq => $pdu->{seq});
122			       }, },
123    0x80010002 => { cmd => 'bind_transmitter_resp_v4', reply => undef, },
124    0x00010003 => { cmd => 'query_sm_v4',
125		    reply => sub { my ($me, $pdu) = @_;
126				   $me->query_sm_resp(message_id=>$pdu->{message_id},
127						      final_date=>'010711135959000+',
128						      seq => $pdu->{seq}) }, },
129    0x80010003 => { cmd => 'query_sm_resp_v4', reply => undef, },
130    0x00010004 => { cmd => 'submit_sm_v4',
131		    reply => sub { my ($me, $pdu) = @_;
132				   $me->submit_sm_resp(message_id=>'123456789',
133#						       num_unsuccess=>0,
134#						       destination_addr=>$pdu->{source_addr},
135						       error_status_code => 0,
136						       seq => $pdu->{seq} ) }, },
137    0x80010004 => { cmd => 'submit_sm_resp_v4', reply => undef, },
138    0x00010005 => { cmd => 'deliver_sm_v4', reply => undef, },
139    0x80010005 => { cmd => 'deliver_sm_resp_v4', reply => undef, },  # Need to handle this?
140    0x00010006 => { cmd => 'unbind_v4',
141		    reply => sub { my ($me, $pdu) = @_;
142				   $me->unbind_resp(seq => $pdu->{seq});
143				   warn "$$: Remote sent unbind. Dropping connection.";
144				   exit;
145			       }, },
146    0x80010006 => { cmd => 'unbind_resp_v4',
147		    reply => sub { warn "$$: Remote replied to unbind. Dropping connection.";
148				   exit;
149			       }, },
150    0x00010007 => { cmd => 'replace_sm_v4',
151		    reply => sub { my ($me, $pdu) = @_;
152				   $me->replace_sm_resp(seq => $pdu->{seq}) }, },
153    0x80010007 => { cmd => 'replace_sm_resp_v4', reply => undef, },
154    0x00010008 => { cmd => 'cancel_sm_v4',
155		    reply => sub { my ($me, $pdu) = @_;
156				   $me->cancel_resp(seq => $pdu->{seq}) }, },
157    0x80010008 => { cmd => 'cancel_sm_resp_v4', reply => undef, },
158    0x00010009 => { cmd => 'delivery_receipt_v4',
159		    reply => sub { my ($me, $pdu) = @_;
160				   $me->delivery_receipt_resp(seq => $pdu->{seq}) }, },
161    0x80010009 => { cmd => 'delivery_receipt_resp_v4', reply => undef, },
162    0x0001000a => { cmd => 'enquire_link_v4',
163		    reply => sub { my ($me, $pdu) = @_;
164				   $me->enquire_link_resp(seq => $pdu->{seq}) }, },
165    0x8001000a => { cmd => 'enquire_link_resp_v4', reply => undef, },
166    0x0001000b => { cmd => 'outbind_v4',
167		    reply => sub { my ($me, $pdu) = @_;
168				   $me->set_version(0x34);
169				   $me->bind_receiver(system_id => $sysid,
170						      password => $pw,
171						      facilities_mask => $facil,
172						      seq => $pdu->{seq}) }, },
173#4#end
174};
175
176$smpp = Net::SMPP->new_receiver($host,
177			      smpp_version => $vers,
178			      interface_version => $if_vers,
179			      system_id => $sysid,
180			      password => $pw,
181			      addr_ton => 0x09,
182			      addr_npi => 0x00,
183			      source_addr_ton => 0x09,
184			      source_addr_npi => 0x00,
185			      dest_addr_ton => 0x09,
186			      dest_addr_npi => 0x00,
187			      system_type => '_001',
188			      facilities_mask => $facil,
189			      port => $port,
190#				timeout => 7,
191			      )
192    or die "Can't create server: $!";
193
194while (1) {
195    warn "Waiting for PDU";
196    $pdu = $smpp->read_pdu() or die "$$: PDU not read. Closing connection";
197    print "Received #$pdu->{seq} $pdu->{cmd}:". Net::SMPP::pdu_tab->{$pdu->{cmd}}{cmd} ."\n"
198	;
199    warn Dumper($pdu) if $trace;
200
201    if (defined reply_tab->{$pdu->{cmd}}) {
202	&{reply_tab->{$pdu->{cmd}}{reply}}($c, $pdu);
203	warn "Replied";
204    } else {
205	warn "Don't know to reply to $pdu->{cmd}";
206	sleep 1;
207    }
208}
209
210#EOF
211