/smsc.pl

https://github.com/gitpan/Net-SMPP · Perl · 226 lines · 190 code · 14 blank · 22 comment · 7 complexity · 502936781f53c2fe564e36293e5b5293 MD5 · raw file

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