ruby-smpp 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem "jeweler"
4
+ gem "rake"
5
+ gem "eventmachine"
@@ -0,0 +1,22 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ eventmachine (0.12.10)
5
+ gemcutter (0.6.1)
6
+ git (1.2.5)
7
+ jeweler (1.4.0)
8
+ gemcutter (>= 0.1.0)
9
+ git (>= 1.2.5)
10
+ rubyforge (>= 2.0.0)
11
+ json_pure (1.4.6)
12
+ rake (0.8.7)
13
+ rubyforge (2.0.4)
14
+ json_pure (>= 1.1.7)
15
+
16
+ PLATFORMS
17
+ ruby
18
+
19
+ DEPENDENCIES
20
+ eventmachine
21
+ jeweler
22
+ rake
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require 'rubygems'
1
+ require File.expand_path('../config/environment', __FILE__)
2
2
  require 'rake'
3
3
 
4
4
  begin
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -0,0 +1,2 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
@@ -10,6 +10,7 @@ require 'logger'
10
10
  $:.unshift(File.dirname(__FILE__))
11
11
  require 'smpp/base.rb'
12
12
  require 'smpp/transceiver.rb'
13
+ require 'smpp/receiver.rb'
13
14
  require 'smpp/optional_parameter'
14
15
  require 'smpp/pdu/base.rb'
15
16
  require 'smpp/pdu/bind_base.rb'
@@ -0,0 +1,4 @@
1
+ class Smpp::Pdu::BindReceiver < Smpp::Pdu::BindBase
2
+ @command_id = BIND_RECEIVER
3
+ handles_cmd BIND_RECEIVER
4
+ end
@@ -0,0 +1,4 @@
1
+ class Smpp::Pdu::BindReceiverResponse < Smpp::Pdu::BindRespBase
2
+ @command_id = BIND_RECEIVER_RESP
3
+ handles_cmd BIND_RECEIVER_RESP
4
+ end
@@ -27,7 +27,7 @@ class Smpp::Pdu::DeliverSm < Smpp::Pdu::Base
27
27
  @data_coding = options[:data_coding]?options[:data_coding]:3 # iso-8859-1
28
28
  @sm_default_msg_id = options[:sm_default_msg_id]?options[:sm_default_msg_id]:0
29
29
  @short_message = short_message
30
- payload = @udh ? @udh + @short_message : @short_message
30
+ payload = @udh ? @udh.to_s + @short_message : @short_message
31
31
  @sm_length = payload.length
32
32
 
33
33
  #fields set for delivery report
@@ -46,6 +46,18 @@ class Smpp::Pdu::DeliverSm < Smpp::Pdu::Base
46
46
  super(DELIVER_SM, 0, seq, pdu_body)
47
47
  end
48
48
 
49
+ def total_parts
50
+ @udh ? @udh[4] : 0
51
+ end
52
+
53
+ def part
54
+ @udh ? @udh[5] : 0
55
+ end
56
+
57
+ def message_id
58
+ @udh ? @udh[3] : 0
59
+ end
60
+
49
61
  def self.from_wire_data(seq, status, body)
50
62
  options = {}
51
63
  # brutally unpack it
@@ -85,7 +97,10 @@ class Smpp::Pdu::DeliverSm < Smpp::Pdu::Base
85
97
  end
86
98
  end
87
99
 
88
-
100
+ # Check to see if body has a 5 bit header
101
+ if short_message.unpack("c")[0] == 5
102
+ options[:udh] = short_message.slice!(0..5).unpack("CCCCCC")
103
+ end
89
104
 
90
105
  #Note: if the SM is a delivery receipt (esm_class=4) then the short_message _may_ be in this format:
91
106
  # "id:Smsc2013 sub:1 dlvrd:1 submit date:0610171515 done date:0610171515 stat:0 err:0 text:blah"
@@ -0,0 +1,80 @@
1
+
2
+ # The SMPP Receiver maintains a unidirectional connection to an SMSC.
3
+ # Provide a config hash with connection options to get started.
4
+ # See the sample_gateway.rb for examples of config values.
5
+ # The receiver accepts a delegate object that may implement
6
+ # the following (all optional) methods:
7
+ #
8
+ # mo_received(receiver, pdu)
9
+ # delivery_report_received(receiver, pdu)
10
+ # bound(receiver)
11
+ # unbound(receiver)
12
+
13
+ class Smpp::Receiver < Smpp::Base
14
+
15
+ def initialize(config, delegate)
16
+ super(config)
17
+ @delegate = delegate
18
+
19
+ ed = @config[:enquire_link_delay_secs] || 5
20
+ comm_inactivity_timeout = 2 * ed
21
+ rescue Exception => ex
22
+ logger.error "Exception setting up receiver: #{ex} at #{ex.backtrace.join("\n")}"
23
+ raise
24
+ end
25
+
26
+ # a PDU is received. Parse it and invoke delegate methods.
27
+ def process_pdu(pdu)
28
+ case pdu
29
+ when Pdu::DeliverSm
30
+ write_pdu(Pdu::DeliverSmResponse.new(pdu.sequence_number))
31
+ logger.debug "ESM CLASS #{pdu.esm_class}"
32
+ if pdu.esm_class != 4
33
+ # MO message
34
+ if @delegate.respond_to?(:mo_received)
35
+ @delegate.mo_received(self, pdu)
36
+ end
37
+ else
38
+ # Delivery report
39
+ if @delegate.respond_to?(:delivery_report_received)
40
+ @delegate.delivery_report_received(self, pdu)
41
+ end
42
+ end
43
+ when Pdu::BindReceiverResponse
44
+ case pdu.command_status
45
+ when Pdu::Base::ESME_ROK
46
+ logger.debug "Bound OK."
47
+ @state = :bound
48
+ if @delegate.respond_to?(:bound)
49
+ @delegate.bound(self)
50
+ end
51
+ when Pdu::Base::ESME_RINVPASWD
52
+ logger.warn "Invalid password."
53
+ # scheduele the connection to close, which eventually will cause the unbound() delegate
54
+ # method to be invoked.
55
+ close_connection
56
+ when Pdu::Base::ESME_RINVSYSID
57
+ logger.warn "Invalid system id."
58
+ close_connection
59
+ else
60
+ logger.warn "Unexpected BindReceiverResponse. Command status: #{pdu.command_status}"
61
+ close_connection
62
+ end
63
+ else
64
+ super
65
+ end
66
+ end
67
+
68
+ # Send BindReceiverResponse PDU.
69
+ def send_bind
70
+ raise IOError, 'Receiver already bound.' unless unbound?
71
+ pdu = Pdu::BindReceiver.new(
72
+ @config[:system_id],
73
+ @config[:password],
74
+ @config[:system_type],
75
+ @config[:source_ton],
76
+ @config[:source_npi],
77
+ @config[:source_address_range])
78
+ write_pdu(pdu)
79
+ end
80
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruby-smpp}
8
- s.version = "0.3.0"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ray Krueger", "August Z. Flatby"]
12
- s.date = %q{2010-06-14}
12
+ s.date = %q{2011-01-06}
13
13
  s.description = %q{Ruby implementation of the SMPP protocol, based on EventMachine. SMPP is a protocol that allows ordinary people outside the mobile network to exchange SMS messages directly with mobile operators.}
14
14
  s.email = %q{raykrueger@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -21,10 +21,13 @@ Gem::Specification.new do |s|
21
21
  ".gitignore",
22
22
  "CHANGELOG",
23
23
  "CONTRIBUTORS.txt",
24
+ "Gemfile",
25
+ "Gemfile.lock",
24
26
  "LICENSE",
25
27
  "README.rdoc",
26
28
  "Rakefile",
27
29
  "VERSION",
30
+ "config/environment.rb",
28
31
  "examples/PDU1.example",
29
32
  "examples/PDU2.example",
30
33
  "examples/sample_gateway.rb",
@@ -34,6 +37,8 @@ Gem::Specification.new do |s|
34
37
  "lib/smpp/optional_parameter.rb",
35
38
  "lib/smpp/pdu/base.rb",
36
39
  "lib/smpp/pdu/bind_base.rb",
40
+ "lib/smpp/pdu/bind_receiver.rb",
41
+ "lib/smpp/pdu/bind_receiver_response.rb",
37
42
  "lib/smpp/pdu/bind_resp_base.rb",
38
43
  "lib/smpp/pdu/bind_transceiver.rb",
39
44
  "lib/smpp/pdu/bind_transceiver_response.rb",
@@ -48,11 +53,17 @@ Gem::Specification.new do |s|
48
53
  "lib/smpp/pdu/submit_sm_response.rb",
49
54
  "lib/smpp/pdu/unbind.rb",
50
55
  "lib/smpp/pdu/unbind_response.rb",
56
+ "lib/smpp/receiver.rb",
51
57
  "lib/smpp/server.rb",
52
58
  "lib/smpp/transceiver.rb",
53
59
  "lib/sms.rb",
54
60
  "ruby-smpp.gemspec",
61
+ "test/delegate.rb",
55
62
  "test/optional_parameter_test.rb",
63
+ "test/pdu_parsing_test.rb",
64
+ "test/receiver_test.rb",
65
+ "test/responsive_delegate.rb",
66
+ "test/server.rb",
56
67
  "test/smpp_test.rb",
57
68
  "test/submit_sm_test.rb"
58
69
  ]
@@ -63,7 +74,12 @@ Gem::Specification.new do |s|
63
74
  s.rubygems_version = %q{1.3.6}
64
75
  s.summary = %q{Ruby implementation of the SMPP protocol, based on EventMachine.}
65
76
  s.test_files = [
66
- "test/optional_parameter_test.rb",
77
+ "test/delegate.rb",
78
+ "test/optional_parameter_test.rb",
79
+ "test/pdu_parsing_test.rb",
80
+ "test/receiver_test.rb",
81
+ "test/responsive_delegate.rb",
82
+ "test/server.rb",
67
83
  "test/smpp_test.rb",
68
84
  "test/submit_sm_test.rb",
69
85
  "examples/sample_gateway.rb",
@@ -0,0 +1,28 @@
1
+ # the delagate receives callbacks when interesting things happen on the connection
2
+ class Delegate
3
+
4
+ def mo_received(transceiver, pdu)
5
+ puts "** mo_received"
6
+ end
7
+
8
+ def delivery_report_received(transceiver, pdu)
9
+ puts "** delivery_report_received"
10
+ end
11
+
12
+ def message_accepted(transceiver, mt_message_id, pdu)
13
+ puts "** message_sent"
14
+ end
15
+
16
+ def message_rejected(transceiver, mt_message_id, pdu)
17
+ puts "** message_rejected"
18
+ end
19
+
20
+ def bound(transceiver)
21
+ puts "** bound"
22
+ end
23
+
24
+ def unbound(transceiver)
25
+ puts "** unbound"
26
+ EventMachine::stop_event_loop
27
+ end
28
+ end
@@ -0,0 +1,84 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require File.expand_path(File.dirname(__FILE__) + "../../lib/smpp")
4
+
5
+ class PduParsingTest < Test::Unit::TestCase
6
+
7
+ def test_recieve_single_message
8
+ raw_data = <<-EOF
9
+ 0000 003d 0000 0005 0000 0000 0000 0002
10
+ 0001 0134 3437 3830 3330 3239 3833 3700
11
+ 0101 3434 3738 3033 3032 3938 3337 0000
12
+ 0000 0000 0000 0000 0454 6573 74
13
+ EOF
14
+
15
+ pdu = create_pdu(raw_data)
16
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
17
+ assert_equal "447803029837", pdu.source_addr
18
+ assert_equal "447803029837", pdu.destination_addr
19
+ assert_nil pdu.udh
20
+ assert_equal "Test", pdu.short_message
21
+ end
22
+
23
+ def test_recieve_part_one_of_multi_part_message
24
+ part_one_message = <<-EOF
25
+ 0000 00d8 0000 0005 0000 0000 0000 0001
26
+ 0001 0134 3437 3937 3334 3238 3634 3400
27
+ 0101 3434 3739 3736 3232 3430 3137 0000
28
+ 0000 0000 0000 0000 9f05 0003 b402 0154
29
+ 6869 7320 6973 2061 206c 6f6e 6720 6d65
30
+ 7373 6167 6520 746f 2074 6573 7420 7768
31
+ 6574 6865 7220 6f72 206e 6f74 2077 6520
32
+ 6765 7420 7468 6520 6865 6164 6572 2069
33
+ 6e66 6f20 7669 6120 7468 6520 534d 5343
34
+ 2074 6861 7420 7765 2077 6f75 6c64 2072
35
+ 6571 7569 7265 2074 6f20 6265 2061 626c
36
+ 6520 746f 2072 6563 6f6d 706f 7365 206c
37
+ 6f6e 6720 6d65 7373 6167 6573 2069 6e20
38
+ 6861 7368 626c 7565
39
+ EOF
40
+
41
+ pdu = create_pdu(part_one_message)
42
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
43
+ assert_equal "447973428644", pdu.source_addr
44
+ assert_equal "447976224017", pdu.destination_addr
45
+ assert_equal [5, 0, 3, 180, 2, 1], pdu.udh
46
+
47
+ assert_equal 2, pdu.total_parts, "Have total parts of the message"
48
+ assert_equal 1, pdu.part, "Correctly show the part"
49
+ assert_equal 180, pdu.message_id
50
+
51
+ assert_equal "This is a long message to test whether or not we get the header info via the SMSC that we would require to be able to recompose long messages in hashblue", pdu.short_message
52
+ end
53
+
54
+ def test_recieve_part_two_of_multi_part_message
55
+ part_one_message = <<-EOF
56
+ 0000 0062 0000 0005 0000 0000 0000 0002
57
+ 0001 0134 3437 3937 3334 3238 3634 3400
58
+ 0101 3434 3739 3736 3232 3430 3137 0000
59
+ 0000 0000 0000 0000 2905 0003 b402 0220
60
+ 616e 6420 7072 6f76 6964 6520 6120 676f
61
+ 6f64 2075 7365 7220 6578 7065 7269 656e
62
+ 6365
63
+ EOF
64
+
65
+ pdu = create_pdu(part_one_message)
66
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
67
+ assert_equal "447973428644", pdu.source_addr
68
+ assert_equal "447976224017", pdu.destination_addr
69
+ assert_equal [5, 0, 3, 180, 2, 2], pdu.udh
70
+
71
+ assert_equal 2, pdu.total_parts, "Have total parts of the message"
72
+ assert_equal 2, pdu.part, "Correctly show the part"
73
+ assert_equal 180, pdu.message_id
74
+
75
+ assert_equal " and provide a good user experience", pdu.short_message
76
+ end
77
+
78
+ protected
79
+ def create_pdu(raw_data)
80
+ hex_data = [raw_data.chomp.gsub(" ","").gsub(/\n/,"")].pack("H*")
81
+ Smpp::Pdu::Base.create(hex_data)
82
+ end
83
+
84
+ end
@@ -0,0 +1,197 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'smpp'
4
+
5
+ class ReceiverTest < Test::Unit::TestCase
6
+
7
+ class RecordingDelegate
8
+ attr_reader :received_pdus, :received_delivery_report_pdus, :states
9
+ def initialize
10
+ @received_pdus, @received_delivery_report_pdus, @states = [], [], []
11
+ end
12
+ def mo_received(receiver, pdu)
13
+ @received_pdus << pdu
14
+ end
15
+ def delivery_report_received(receiver, pdu)
16
+ @received_delivery_report_pdus << pdu
17
+ end
18
+ def bound(receiver)
19
+ @states << :bound
20
+ end
21
+ end
22
+
23
+ def test_receiving_bind_receiver_response_with_ok_status_should_become_bound
24
+ receiver = build_receiver
25
+ bind_receiver_response = Smpp::Pdu::BindReceiverResponse.new(nil, Smpp::Pdu::Base::ESME_ROK, 1)
26
+
27
+ receiver.process_pdu(bind_receiver_response)
28
+
29
+ assert receiver.bound?
30
+ end
31
+
32
+ def test_receiving_bind_receiver_response_with_ok_status_should_invoke_bound_on_delegate
33
+ delegate = RecordingDelegate.new
34
+ receiver = build_receiver(delegate)
35
+ bind_receiver_response = Smpp::Pdu::BindReceiverResponse.new(nil, Smpp::Pdu::Base::ESME_ROK, 1)
36
+
37
+ receiver.process_pdu(bind_receiver_response)
38
+
39
+ assert_equal [:bound], delegate.states
40
+ end
41
+
42
+ def test_receiving_bind_receiver_response_with_ok_status_should_not_error_if_method_doesnt_exist_on_delegate
43
+ delegate = Object.new
44
+ receiver = build_receiver(delegate)
45
+ bind_receiver_response = Smpp::Pdu::BindReceiverResponse.new(nil, Smpp::Pdu::Base::ESME_ROK, 1)
46
+
47
+ assert_nothing_raised { receiver.process_pdu(bind_receiver_response) }
48
+ end
49
+
50
+ def test_receiving_bind_receiver_response_with_error_status_should_not_become_bound
51
+ receiver = build_receiver
52
+ bind_receiver_response = Smpp::Pdu::BindReceiverResponse.new(nil, Smpp::Pdu::Base::ESME_RBINDFAIL, 1)
53
+
54
+ receiver.process_pdu(bind_receiver_response)
55
+
56
+ assert receiver.unbound?
57
+ end
58
+
59
+ def test_receiving_bind_receiver_response_with_error_status_should_not_invoke_bound_on_delegate
60
+ delegate = RecordingDelegate.new
61
+ receiver = build_receiver(delegate)
62
+ bind_receiver_response = Smpp::Pdu::BindReceiverResponse.new(nil, Smpp::Pdu::Base::ESME_RBINDFAIL, 1)
63
+
64
+ receiver.process_pdu(bind_receiver_response)
65
+
66
+ assert_equal [], delegate.states
67
+ end
68
+
69
+ def test_receiving_bind_receiver_response_with_error_status_should_close_connection
70
+ receiver = build_receiver
71
+ bind_receiver_response = Smpp::Pdu::BindReceiverResponse.new(nil, Smpp::Pdu::Base::ESME_RBINDFAIL, 1)
72
+
73
+ receiver.process_pdu(bind_receiver_response)
74
+
75
+ assert_equal 1, receiver.close_connections
76
+ end
77
+
78
+ def test_receiving_deliver_sm_should_send_deliver_sm_response
79
+ receiver = build_receiver
80
+ deliver_sm = Smpp::Pdu::DeliverSm.new("from", "to", "message")
81
+
82
+ receiver.process_pdu(deliver_sm)
83
+
84
+ first_sent_data = receiver.sent_data.first
85
+ assert_not_nil first_sent_data
86
+ actual_response = Smpp::Pdu::Base.create(first_sent_data)
87
+ expected_response = Smpp::Pdu::DeliverSmResponse.new(deliver_sm.sequence_number)
88
+ assert_equal expected_response.to_human, actual_response.to_human
89
+ end
90
+
91
+ def test_receiving_deliver_sm_should_invoke_mo_received_on_delegate
92
+ delegate = RecordingDelegate.new
93
+ receiver = build_receiver(delegate)
94
+ deliver_sm = Smpp::Pdu::DeliverSm.new("from", "to", "message")
95
+
96
+ receiver.process_pdu(deliver_sm)
97
+
98
+ first_received_pdu = delegate.received_pdus.first
99
+ assert_not_nil first_received_pdu
100
+ assert_equal deliver_sm.to_human, first_received_pdu.to_human
101
+ end
102
+
103
+ def test_receiving_deliver_sm_should_not_error_if_mo_received_method_doesnt_exist_on_delegate
104
+ delegate = Object.new
105
+ receiver = build_receiver(delegate)
106
+ deliver_sm = Smpp::Pdu::DeliverSm.new("from", "to", "message")
107
+
108
+ assert_nothing_raised { receiver.process_pdu(deliver_sm) }
109
+ end
110
+
111
+ def test_receiving_deliver_sm_for_esm_class_4_should_invoke_delivery_report_received_on_delegate
112
+ delegate = RecordingDelegate.new
113
+ receiver = build_receiver(delegate)
114
+ deliver_sm = Smpp::Pdu::DeliverSm.new("from", "to", "message", :esm_class => 4)
115
+
116
+ receiver.process_pdu(deliver_sm)
117
+
118
+ first_received_delivery_report_pdu = delegate.received_delivery_report_pdus.first
119
+ assert_not_nil first_received_delivery_report_pdu
120
+ assert_equal deliver_sm.to_human, first_received_delivery_report_pdu.to_human
121
+ end
122
+
123
+ def test_receiving_deliver_sm_should_not_error_if_received_delivery_report_method_doesnt_exist_on_delegate
124
+ delegate = Object.new
125
+ receiver = build_receiver(delegate)
126
+ deliver_sm = Smpp::Pdu::DeliverSm.new("from", "to", "message", :esm_class => 4)
127
+
128
+ assert_nothing_raised { receiver.process_pdu(deliver_sm) }
129
+ end
130
+
131
+ private
132
+
133
+ def build_receiver(delegate = nil)
134
+ receiver = Smpp::Receiver.new(1, {}, delegate)
135
+ class << receiver
136
+ attr_reader :sent_data, :close_connections
137
+ def send_data(data)
138
+ @sent_data = (@sent_data || []) + [data]
139
+ end
140
+ def close_connection
141
+ @close_connections = (@close_connections || 0) + 1
142
+ end
143
+ end
144
+ receiver
145
+ end
146
+
147
+ end
148
+
149
+ require 'server'
150
+ require 'delegate'
151
+
152
+ class SmppTest < Test::Unit::TestCase
153
+
154
+ def config
155
+ Server::config
156
+ end
157
+
158
+ def test_transceiver_should_bind_and_unbind_then_stop
159
+ EventMachine.run {
160
+ EventMachine.start_server "localhost", 9000, Server::Unbind
161
+ EventMachine.connect "localhost", 9000, Smpp::Receiver, config, Delegate.new
162
+ }
163
+ # should not hang here: the server's response should have caused the client to terminate
164
+ end
165
+
166
+ def test_bind_receiver
167
+ pdu1 = Smpp::Pdu::BindReceiver.new(
168
+ config[:system_id],
169
+ config[:password],
170
+ config[:system_type],
171
+ config[:source_ton],
172
+ config[:source_npi],
173
+ config[:source_address_range]
174
+ )
175
+
176
+ pdu2 = Smpp::Pdu::Base.create(pdu1.data)
177
+
178
+ assert_instance_of(Smpp::Pdu::BindReceiver, pdu2)
179
+ assert_equal(pdu1.system_id, pdu2.system_id)
180
+ assert_equal(pdu1.password, pdu2.password)
181
+ assert_equal(pdu1.system_type, pdu2.system_type)
182
+ assert_equal(pdu1.addr_ton, pdu2.addr_ton)
183
+ assert_equal(pdu1.addr_npi, pdu2.addr_npi)
184
+ assert_equal(pdu1.address_range, pdu2.address_range)
185
+ assert_equal(pdu1.sequence_number, pdu2.sequence_number)
186
+ assert_equal(pdu1.command_status, pdu2.command_status)
187
+ end
188
+
189
+ def test_bind_receiver_response
190
+ pdu1 = Smpp::Pdu::BindReceiverResponse.new(nil, Smpp::Pdu::Base::ESME_ROK, config[:system_id])
191
+ pdu2 = Smpp::Pdu::Base.create(pdu1.data)
192
+ assert_instance_of(Smpp::Pdu::BindReceiverResponse, pdu2)
193
+ assert_equal(pdu1.system_id, pdu2.system_id)
194
+ assert_equal(pdu1.sequence_number, pdu2.sequence_number)
195
+ assert_equal(pdu1.command_status, pdu2.command_status)
196
+ end
197
+ end
@@ -0,0 +1,53 @@
1
+ #TODO This should be made prettier with mocha
2
+ class ResponsiveDelegate
3
+ attr_reader :seq, :event_counter
4
+
5
+ def initialize
6
+ @seq = 0
7
+ @event_counter = nil
8
+ end
9
+ def seq
10
+ @seq += 1
11
+ end
12
+ def count_function
13
+ func = caller(1)[0].split("`")[1].split("'")[0].to_sym
14
+ @event_counter = {} unless @event_counter.is_a?(Hash)
15
+ @event_counter[func] = 0 if @event_counter[func].nil?
16
+ @event_counter[func]+=1
17
+ end
18
+
19
+ def mo_received(transceiver, pdu)
20
+ count_function
21
+ puts "** mo_received"
22
+ end
23
+
24
+ def delivery_report_received(transceiver, pdu)
25
+ count_function
26
+ puts "** delivery_report_received"
27
+ end
28
+
29
+ def message_accepted(transceiver, mt_message_id, pdu)
30
+ count_function
31
+ puts "** message_sent"
32
+ #sending messages from delegate to escape making a fake message sender - not nice :(
33
+ $tx.send_mt(self.seq, 1, 2, "short_message @ message_accepted")
34
+ end
35
+
36
+ def message_rejected(transceiver, mt_message_id, pdu)
37
+ count_function
38
+ puts "** message_rejected"
39
+ $tx.send_mt(self.seq, 1, 2, "short_message @ message_rejected")
40
+ end
41
+
42
+ def bound(transceiver)
43
+ count_function
44
+ puts "** bound"
45
+ $tx.send_mt(self.seq, 1, 2, "short_message @ bound")
46
+ end
47
+
48
+ def unbound(transceiver)
49
+ count_function
50
+ puts "** unbound"
51
+ EventMachine::stop_event_loop
52
+ end
53
+ end
@@ -0,0 +1,56 @@
1
+ # a server which immediately requests the client to unbind
2
+ module Server
3
+ def self.config
4
+ {
5
+ :host => 'localhost',
6
+ :port => 2775,
7
+ :system_id => 'foo',
8
+ :password => 'bar',
9
+ :system_type => '',
10
+ :source_ton => 0,
11
+ :source_npi => 1,
12
+ :destination_ton => 1,
13
+ :destination_npi => 1,
14
+ :source_address_range => '',
15
+ :destination_address_range => ''
16
+ }
17
+ end
18
+
19
+ module Unbind
20
+ def receive_data(data)
21
+ send_data Smpp::Pdu::Unbind.new.data
22
+ end
23
+ end
24
+
25
+ module SubmitSmResponse
26
+ def receive_data(data)
27
+ # problem: our Pdu's should have factory methods for "both ways"; ie. when created
28
+ # by client, and when created from wire data.
29
+ send_data Smpp::Pdu::SubmitSmResponse.new(1, 2, "100").data
30
+ end
31
+ end
32
+
33
+ module SubmitSmResponseWithErrorStatus
34
+ attr_reader :state #state=nil => bind => state=bound => send =>state=sent => unbind => state=unbound
35
+ def receive_data(data)
36
+ if @state.nil?
37
+ @state = 'bound'
38
+ pdu = Smpp::Pdu::Base.create(data)
39
+ response_pdu = Smpp::Pdu::BindTransceiverResponse.new(pdu.sequence_number,Smpp::Pdu::Base::ESME_ROK,Server::config[:system_id])
40
+ send_data response_pdu.data
41
+ elsif @state == 'bound'
42
+ @state = 'sent'
43
+ pdu = Smpp::Pdu::Base.create(data)
44
+ pdu.to_human
45
+ send_data Smpp::Pdu::SubmitSmResponse.new(pdu.sequence_number, Smpp::Pdu::Base::ESME_RINVDSTADR, pdu.body).data
46
+ #send_data Smpp::Pdu::SubmitSmResponse.new(1, 2, "100").data
47
+ elsif @state == 'sent'
48
+ @state = 'unbound'
49
+ send_data Smpp::Pdu::Unbind.new.data
50
+ else
51
+ raise "unexpected state"
52
+ end
53
+ end
54
+ end
55
+
56
+ end
@@ -1,147 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
3
  require 'smpp'
4
-
5
- # a server which immediately requests the client to unbind
6
- module Server
7
- def self.config
8
- {
9
- :host => 'localhost',
10
- :port => 2775,
11
- :system_id => 'foo',
12
- :password => 'bar',
13
- :system_type => '',
14
- :source_ton => 0,
15
- :source_npi => 1,
16
- :destination_ton => 1,
17
- :destination_npi => 1,
18
- :source_address_range => '',
19
- :destination_address_range => ''
20
- }
21
- end
22
-
23
- module Unbind
24
- def receive_data(data)
25
- send_data Smpp::Pdu::Unbind.new.data
26
- end
27
- end
28
-
29
- module SubmitSmResponse
30
- def receive_data(data)
31
- # problem: our Pdu's should have factory methods for "both ways"; ie. when created
32
- # by client, and when created from wire data.
33
- send_data Smpp::Pdu::SubmitSmResponse.new(1, 2, "100").data
34
- end
35
- end
36
-
37
- module SubmitSmResponseWithErrorStatus
38
- attr_reader :state #state=nil => bind => state=bound => send =>state=sent => unbind => state=unbound
39
- def receive_data(data)
40
- if @state.nil?
41
- @state = 'bound'
42
- pdu = Smpp::Pdu::Base.create(data)
43
- response_pdu = Smpp::Pdu::BindTransceiverResponse.new(pdu.sequence_number,Smpp::Pdu::Base::ESME_ROK,Server::config[:system_id])
44
- send_data response_pdu.data
45
- elsif @state == 'bound'
46
- @state = 'sent'
47
- pdu = Smpp::Pdu::Base.create(data)
48
- pdu.to_human
49
- send_data Smpp::Pdu::SubmitSmResponse.new(pdu.sequence_number, Smpp::Pdu::Base::ESME_RINVDSTADR, pdu.body).data
50
- #send_data Smpp::Pdu::SubmitSmResponse.new(1, 2, "100").data
51
- elsif @state == 'sent'
52
- @state = 'unbound'
53
- send_data Smpp::Pdu::Unbind.new.data
54
- else
55
- raise "unexpected state"
56
- end
57
- end
58
- end
59
-
60
- end
61
-
62
-
63
- # the delagate receives callbacks when interesting things happen on the connection
64
- class Delegate
65
-
66
- def mo_received(transceiver, pdu)
67
- puts "** mo_received"
68
- end
69
-
70
- def delivery_report_received(transceiver, pdu)
71
- puts "** delivery_report_received"
72
- end
73
-
74
- def message_accepted(transceiver, mt_message_id, pdu)
75
- puts "** message_sent"
76
- end
77
-
78
- def message_rejected(transceiver, mt_message_id, pdu)
79
- puts "** message_rejected"
80
- end
81
-
82
- def bound(transceiver)
83
- puts "** bound"
84
- end
85
-
86
- def unbound(transceiver)
87
- puts "** unbound"
88
- EventMachine::stop_event_loop
89
- end
90
- end
91
-
92
- #TODO This should be made prettier with mocha
93
- class ResponsiveDelegate
94
- attr_reader :seq, :event_counter
95
-
96
- def initialize
97
- @seq = 0
98
- @event_counter = nil
99
- end
100
- def seq
101
- @seq += 1
102
- end
103
- def count_function
104
- func = caller(1)[0].split("`")[1].split("'")[0].to_sym
105
- @event_counter = {} unless @event_counter.is_a?(Hash)
106
- @event_counter[func] = 0 if @event_counter[func].nil?
107
- @event_counter[func]+=1
108
- end
109
-
110
- def mo_received(transceiver, pdu)
111
- count_function
112
- puts "** mo_received"
113
- end
114
-
115
- def delivery_report_received(transceiver, pdu)
116
- count_function
117
- puts "** delivery_report_received"
118
- end
119
-
120
- def message_accepted(transceiver, mt_message_id, pdu)
121
- count_function
122
- puts "** message_sent"
123
- #sending messages from delegate to escape making a fake message sender - not nice :(
124
- $tx.send_mt(self.seq, 1, 2, "short_message @ message_accepted")
125
- end
126
-
127
- def message_rejected(transceiver, mt_message_id, pdu)
128
- count_function
129
- puts "** message_rejected"
130
- $tx.send_mt(self.seq, 1, 2, "short_message @ message_rejected")
131
- end
132
-
133
- def bound(transceiver)
134
- count_function
135
- puts "** bound"
136
- $tx.send_mt(self.seq, 1, 2, "short_message @ bound")
137
- end
138
-
139
- def unbound(transceiver)
140
- count_function
141
- puts "** unbound"
142
- EventMachine::stop_event_loop
143
- end
144
- end
4
+ require 'server'
5
+ require 'delegate'
6
+ require 'responsive_delegate'
145
7
 
146
8
  class Poller
147
9
  def start
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
7
+ - 4
8
8
  - 0
9
- version: 0.3.0
9
+ version: 0.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ray Krueger
@@ -15,13 +15,13 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-14 00:00:00 -05:00
18
+ date: 2011-01-06 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: eventmachine
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
23
+ type: :runtime
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
@@ -30,8 +30,8 @@ dependencies:
30
30
  - 10
31
31
  - 0
32
32
  version: 0.10.0
33
- type: :runtime
34
- version_requirements: *id001
33
+ prerelease: false
34
+ requirement: *id001
35
35
  description: Ruby implementation of the SMPP protocol, based on EventMachine. SMPP is a protocol that allows ordinary people outside the mobile network to exchange SMS messages directly with mobile operators.
36
36
  email: raykrueger@gmail.com
37
37
  executables: []
@@ -46,10 +46,13 @@ files:
46
46
  - .gitignore
47
47
  - CHANGELOG
48
48
  - CONTRIBUTORS.txt
49
+ - Gemfile
50
+ - Gemfile.lock
49
51
  - LICENSE
50
52
  - README.rdoc
51
53
  - Rakefile
52
54
  - VERSION
55
+ - config/environment.rb
53
56
  - examples/PDU1.example
54
57
  - examples/PDU2.example
55
58
  - examples/sample_gateway.rb
@@ -59,6 +62,8 @@ files:
59
62
  - lib/smpp/optional_parameter.rb
60
63
  - lib/smpp/pdu/base.rb
61
64
  - lib/smpp/pdu/bind_base.rb
65
+ - lib/smpp/pdu/bind_receiver.rb
66
+ - lib/smpp/pdu/bind_receiver_response.rb
62
67
  - lib/smpp/pdu/bind_resp_base.rb
63
68
  - lib/smpp/pdu/bind_transceiver.rb
64
69
  - lib/smpp/pdu/bind_transceiver_response.rb
@@ -73,11 +78,17 @@ files:
73
78
  - lib/smpp/pdu/submit_sm_response.rb
74
79
  - lib/smpp/pdu/unbind.rb
75
80
  - lib/smpp/pdu/unbind_response.rb
81
+ - lib/smpp/receiver.rb
76
82
  - lib/smpp/server.rb
77
83
  - lib/smpp/transceiver.rb
78
84
  - lib/sms.rb
79
85
  - ruby-smpp.gemspec
86
+ - test/delegate.rb
80
87
  - test/optional_parameter_test.rb
88
+ - test/pdu_parsing_test.rb
89
+ - test/receiver_test.rb
90
+ - test/responsive_delegate.rb
91
+ - test/server.rb
81
92
  - test/smpp_test.rb
82
93
  - test/submit_sm_test.rb
83
94
  has_rdoc: true
@@ -111,7 +122,12 @@ signing_key:
111
122
  specification_version: 3
112
123
  summary: Ruby implementation of the SMPP protocol, based on EventMachine.
113
124
  test_files:
125
+ - test/delegate.rb
114
126
  - test/optional_parameter_test.rb
127
+ - test/pdu_parsing_test.rb
128
+ - test/receiver_test.rb
129
+ - test/responsive_delegate.rb
130
+ - test/server.rb
115
131
  - test/smpp_test.rb
116
132
  - test/submit_sm_test.rb
117
133
  - examples/sample_gateway.rb