ruby-smpp 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -2,16 +2,12 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  eventmachine (0.12.10)
5
- gemcutter (0.6.1)
6
5
  git (1.2.5)
7
- jeweler (1.4.0)
8
- gemcutter (>= 0.1.0)
6
+ jeweler (1.5.2)
7
+ bundler (~> 1.0.0)
9
8
  git (>= 1.2.5)
10
- rubyforge (>= 2.0.0)
11
- json_pure (1.4.6)
9
+ rake
12
10
  rake (0.8.7)
13
- rubyforge (2.0.4)
14
- json_pure (>= 1.1.7)
15
11
 
16
12
  PLATFORMS
17
13
  ruby
data/README.rdoc CHANGED
@@ -8,6 +8,7 @@ The implementation is based on the Ruby/EventMachine library.
8
8
 
9
9
  <b>NOTE: Breaking change from 0.1.2 to 0.1.3</b>. See below.
10
10
 
11
+ For help please use the Google group here: http://groups.google.com/group/ruby-smpp/topics
11
12
  === Glossary
12
13
 
13
14
 
data/Rakefile CHANGED
@@ -42,8 +42,6 @@ rescue LoadError
42
42
  end
43
43
  end
44
44
 
45
- task :test => :check_dependencies
46
-
47
45
  task :default => :test
48
46
 
49
47
  require 'rake/rdoctask'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.0
data/lib/smpp/base.rb CHANGED
@@ -13,6 +13,22 @@ module Smpp
13
13
  # :bound or :unbound
14
14
  attr_accessor :state
15
15
 
16
+ def initialize(config, delegate)
17
+ @state = :unbound
18
+ @config = config
19
+ @data = ""
20
+ @delegate = delegate
21
+ @pdr_storage = pdr_storage={}
22
+
23
+ # Array of un-acked MT message IDs indexed by sequence number.
24
+ # As soon as we receive SubmitSmResponse we will use this to find the
25
+ # associated message ID, and then create a pending delivery report.
26
+ @ack_ids = {}
27
+
28
+ ed = @config[:enquire_link_delay_secs] || 5
29
+ comm_inactivity_timeout = 2 * ed
30
+ end
31
+
16
32
  # queries the state of the transmitter - is it bound?
17
33
  def unbound?
18
34
  @state == :unbound
@@ -34,11 +50,6 @@ module Smpp
34
50
  @@logger
35
51
  end
36
52
 
37
- def initialize(config)
38
- @state = :unbound
39
- @config = config
40
- @data = ""
41
- end
42
53
 
43
54
  # invoked by EventMachine when connected
44
55
  def post_init
@@ -140,6 +151,99 @@ module Smpp
140
151
  logger.warn "Received NACK! (error code #{pdu.error_code})."
141
152
  # we don't take this lightly: close the connection
142
153
  close_connection
154
+ when Pdu::DeliverSm
155
+ logger.debug "ESM CLASS #{pdu.esm_class}"
156
+ if pdu.esm_class != 4
157
+ # MO message
158
+ begin
159
+ if @delegate.respond_to?(:mo_received)
160
+ @delegate.mo_received(self, pdu)
161
+ end
162
+ write_pdu(Pdu::DeliverSmResponse.new(pdu.sequence_number))
163
+ rescue => e
164
+ logger.warn "Send Receiver Temporary App Error due to #{e.inspect} raised in delegate"
165
+ write_pdu(Pdu::DeliverSmResponse.new(pdu.sequence_number, Pdu::Base::ESME_RX_T_APPN))
166
+ end
167
+ else
168
+ # Delivery report
169
+ if @delegate.respond_to?(:delivery_report_received)
170
+ @delegate.delivery_report_received(self, pdu)
171
+ end
172
+ end
173
+ when Pdu::BindTransceiverResponse
174
+ case pdu.command_status
175
+ when Pdu::Base::ESME_ROK
176
+ logger.debug "Bound OK."
177
+ @state = :bound
178
+ if @delegate.respond_to?(:bound)
179
+ @delegate.bound(self)
180
+ end
181
+ when Pdu::Base::ESME_RINVPASWD
182
+ logger.warn "Invalid password."
183
+ # scheduele the connection to close, which eventually will cause the unbound() delegate
184
+ # method to be invoked.
185
+ close_connection
186
+ when Pdu::Base::ESME_RINVSYSID
187
+ logger.warn "Invalid system id."
188
+ close_connection
189
+ else
190
+ logger.warn "Unexpected BindTransceiverResponse. Command status: #{pdu.command_status}"
191
+ close_connection
192
+ end
193
+ when Pdu::SubmitSmResponse
194
+ mt_message_id = @ack_ids.delete(pdu.sequence_number)
195
+ if !mt_message_id
196
+ raise "Got SubmitSmResponse for unknown sequence_number: #{pdu.sequence_number}"
197
+ end
198
+ if pdu.command_status != Pdu::Base::ESME_ROK
199
+ logger.error "Error status in SubmitSmResponse: #{pdu.command_status}"
200
+ if @delegate.respond_to?(:message_rejected)
201
+ @delegate.message_rejected(self, mt_message_id, pdu)
202
+ end
203
+ else
204
+ logger.info "Got OK SubmitSmResponse (#{pdu.message_id} -> #{mt_message_id})"
205
+ if @delegate.respond_to?(:message_accepted)
206
+ @delegate.message_accepted(self, mt_message_id, pdu)
207
+ end
208
+ end
209
+ # Now we got the SMSC message id; create pending delivery report.
210
+ @pdr_storage[pdu.message_id] = mt_message_id
211
+ when Pdu::SubmitMultiResponse
212
+ mt_message_id = @ack_ids[pdu.sequence_number]
213
+ if !mt_message_id
214
+ raise "Got SubmitMultiResponse for unknown sequence_number: #{pdu.sequence_number}"
215
+ end
216
+ if pdu.command_status != Pdu::Base::ESME_ROK
217
+ logger.error "Error status in SubmitMultiResponse: #{pdu.command_status}"
218
+ if @delegate.respond_to?(:message_rejected)
219
+ @delegate.message_rejected(self, mt_message_id, pdu)
220
+ end
221
+ else
222
+ logger.info "Got OK SubmitMultiResponse (#{pdu.message_id} -> #{mt_message_id})"
223
+ if @delegate.respond_to?(:message_accepted)
224
+ @delegate.message_accepted(self, mt_message_id, pdu)
225
+ end
226
+ end
227
+ when Pdu::BindReceiverResponse
228
+ case pdu.command_status
229
+ when Pdu::Base::ESME_ROK
230
+ logger.debug "Bound OK."
231
+ @state = :bound
232
+ if @delegate.respond_to?(:bound)
233
+ @delegate.bound(self)
234
+ end
235
+ when Pdu::Base::ESME_RINVPASWD
236
+ logger.warn "Invalid password."
237
+ # scheduele the connection to close, which eventually will cause the unbound() delegate
238
+ # method to be invoked.
239
+ close_connection
240
+ when Pdu::Base::ESME_RINVSYSID
241
+ logger.warn "Invalid system id."
242
+ close_connection
243
+ else
244
+ logger.warn "Unexpected BindReceiverResponse. Command status: #{pdu.command_status}"
245
+ close_connection
246
+ end
143
247
  else
144
248
  logger.warn "(#{self.class.name}) Received unexpected PDU: #{pdu.to_human}."
145
249
  close_connection
@@ -0,0 +1,37 @@
1
+ require 'iconv'
2
+
3
+ module Smpp
4
+ module Encoding
5
+
6
+ # This class is not required by smpp.rb at all, you need to bring it in yourself.
7
+ # This class also requires iconv, you'll need to ensure it is installed.
8
+ class Utf8Encoder
9
+
10
+ EURO_TOKEN = "_X_EURO_X_"
11
+
12
+ GSM_ESCAPED_CHARACTERS = {
13
+ ?( => "\173", # {
14
+ ?) => "\175", # }
15
+ 184 => "\174", # |
16
+ ?< => "\133", # [
17
+ ?> => "\135", # ]
18
+ ?= => "\176", # ~
19
+ ?/ => "\134", # \
20
+ 134 => "\252", # ^
21
+ ?e => EURO_TOKEN
22
+ }
23
+
24
+ def encode(data_coding, short_message)
25
+ if data_coding < 2
26
+ sm = short_message.gsub(/\215./) { |match| GSM_ESCAPED_CHARACTERS[match[1]] }
27
+ sm = Iconv.conv("UTF-8", "HP-ROMAN8", sm)
28
+ sm.gsub(EURO_TOKEN, "\342\202\254")
29
+ elsif data_coding == 8
30
+ Iconv.conv("UTF-8", "UTF-16BE", short_message)
31
+ else
32
+ short_message
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -11,6 +11,10 @@ class Smpp::OptionalParameter
11
11
  self.send symbol
12
12
  end
13
13
 
14
+ def to_s
15
+ self.inspect
16
+ end
17
+
14
18
  #class methods
15
19
  class << self
16
20
  def from_wire_data(data)
data/lib/smpp/pdu/base.rb CHANGED
@@ -39,6 +39,8 @@ module Smpp::Pdu
39
39
  ESME_RINVNUMMSGS = 0x00000055 # Invalid number of messages
40
40
  ESME_RTHROTTLED = 0x00000058 # Throttling error (ESME has exceeded allowed message limits)
41
41
 
42
+ ESME_RX_T_APPN = 0x00000064 # ESME Receiver Temporary App Error Code
43
+
42
44
  # PDU types
43
45
  GENERIC_NACK = 0X80000000
44
46
  BIND_RECEIVER = 0X00000001
@@ -166,7 +168,7 @@ module Smpp::Pdu
166
168
  @@cmd_map[command_id] = self
167
169
  end
168
170
 
169
- def Base.optional_parameters(remaining_bytes)
171
+ def Base.parse_optional_parameters(remaining_bytes)
170
172
  optionals = {}
171
173
  while not remaining_bytes.empty?
172
174
  optional = {}
@@ -1,12 +1,16 @@
1
+
1
2
  # Received for MO message or delivery notification
2
3
  class Smpp::Pdu::DeliverSm < Smpp::Pdu::Base
3
4
  handles_cmd DELIVER_SM
5
+
4
6
  attr_reader :service_type, :source_addr_ton, :source_addr_npi, :source_addr, :dest_addr_ton, :dest_addr_npi,
5
7
  :destination_addr, :esm_class, :protocol_id, :priority_flag, :schedule_delivery_time,
6
8
  :validity_period, :registered_delivery, :replace_if_present_flag, :data_coding,
7
9
  :sm_default_msg_id, :sm_length, :stat, :msg_reference, :udh, :short_message,
8
10
  :message_state, :receipted_message_id, :optional_parameters
9
11
 
12
+ @@encoder = nil
13
+
10
14
  def initialize(source_addr, destination_addr, short_message, options={}, seq=nil)
11
15
 
12
16
  @udh = options[:udh]
@@ -83,7 +87,7 @@ class Smpp::Pdu::DeliverSm < Smpp::Pdu::Base
83
87
  short_message = remaining_bytes.slice!(0...options[:sm_length])
84
88
 
85
89
  #everything left in remaining_bytes is 3.4 optional parameters
86
- options[:optional_parameters] = optional_parameters(remaining_bytes)
90
+ options[:optional_parameters] = parse_optional_parameters(remaining_bytes)
87
91
 
88
92
  #parse the 'standard' optional parameters for delivery receipts
89
93
  options[:optional_parameters].each do |tag, tlv|
@@ -123,8 +127,16 @@ class Smpp::Pdu::DeliverSm < Smpp::Pdu::Base
123
127
  Smpp::Base.logger.debug "DeliverSM with source_addr=#{source_addr}, destination_addr=#{destination_addr}, msg_reference=#{options[:msg_reference]}, stat=#{options[:stat]}"
124
128
  else
125
129
  Smpp::Base.logger.debug "DeliverSM with source_addr=#{source_addr}, destination_addr=#{destination_addr}"
126
- end
127
-
130
+ end
131
+
132
+ #yield the data_coding and short_message to the encoder if one is set
133
+ short_message = @@encoder.encode(options[:data_coding], short_message) if @@encoder.respond_to?(:encode)
134
+
128
135
  new(source_addr, destination_addr, short_message, options, seq)
129
136
  end
137
+
138
+ #set an encoder that can be called to yield the data_coding and short_message
139
+ def self.data_encoder=(encoder)
140
+ @@encoder = encoder
141
+ end
130
142
  end
@@ -62,7 +62,7 @@ class Smpp::Pdu::SubmitMulti < Smpp::Pdu::Base
62
62
 
63
63
  }
64
64
 
65
- formatted_array.join('\0');
65
+ formatted_array.join("\0");
66
66
  end
67
67
 
68
68
  end
@@ -81,7 +81,7 @@ class Smpp::Pdu::SubmitSm < Smpp::Pdu::Base
81
81
  short_message = remaining_bytes.slice!(0...options[:sm_length])
82
82
 
83
83
  #everything left in remaining_bytes is 3.4 optional parameters
84
- options[:optional_parameters] = optional_parameters(remaining_bytes)
84
+ options[:optional_parameters] = parse_optional_parameters(remaining_bytes)
85
85
 
86
86
  Smpp::Base.logger.debug "SubmitSM with source_addr=#{source_addr}, destination_addr=#{destination_addr}"
87
87
 
@@ -2,16 +2,30 @@ class Smpp::Pdu::SubmitSmResponse < Smpp::Pdu::Base
2
2
  handles_cmd SUBMIT_SM_RESP
3
3
 
4
4
  attr_accessor :message_id
5
+ attr_accessor :optional_parameters
5
6
 
6
- def initialize(seq, status, message_id)
7
+ def initialize(seq, status, message_id, optional_parameters=nil)
7
8
  seq ||= next_sequence_number
8
9
  body = message_id.to_s + "\000"
9
10
  super(SUBMIT_SM_RESP, status, seq, body)
10
11
  @message_id = message_id
12
+ @optional_parameters = optional_parameters
13
+ end
14
+
15
+ def optional_parameter(tag)
16
+ if optional_parameters
17
+ if param = optional_parameters[tag]
18
+ param.value
19
+ end
20
+ end
11
21
  end
12
22
 
13
23
  def self.from_wire_data(seq, status, body)
14
- message_id = body.chomp("\000")
15
- new(seq, status, message_id)
24
+ message_id, remaining_bytes = body.unpack("Z*a*")
25
+ optionals = nil
26
+ if remaining_bytes && !remaining_bytes.empty?
27
+ optionals = parse_optional_parameters(remaining_bytes)
28
+ end
29
+ new(seq, status, message_id, optionals)
16
30
  end
17
- end
31
+ end
data/lib/smpp/receiver.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  # The SMPP Receiver maintains a unidirectional connection to an SMSC.
3
2
  # Provide a config hash with connection options to get started.
4
3
  # See the sample_gateway.rb for examples of config values.
@@ -12,59 +11,6 @@
12
11
 
13
12
  class Smpp::Receiver < Smpp::Base
14
13
 
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
14
  # Send BindReceiverResponse PDU.
69
15
  def send_bind
70
16
  raise IOError, 'Receiver already bound.' unless unbound?
@@ -77,4 +23,5 @@ class Smpp::Receiver < Smpp::Base
77
23
  @config[:source_address_range])
78
24
  write_pdu(pdu)
79
25
  end
26
+
80
27
  end
@@ -1,4 +1,3 @@
1
-
2
1
  # The SMPP Transceiver maintains a bidirectional connection to an SMSC.
3
2
  # Provide a config hash with connection options to get started.
4
3
  # See the sample_gateway.rb for examples of config values.
@@ -14,23 +13,6 @@
14
13
 
15
14
  class Smpp::Transceiver < Smpp::Base
16
15
 
17
- def initialize(config, delegate, pdr_storage={})
18
- super(config)
19
- @delegate = delegate
20
- @pdr_storage = pdr_storage
21
-
22
- # Array of un-acked MT message IDs indexed by sequence number.
23
- # As soon as we receive SubmitSmResponse we will use this to find the
24
- # associated message ID, and then create a pending delivery report.
25
- @ack_ids = {}
26
-
27
- ed = @config[:enquire_link_delay_secs] || 5
28
- comm_inactivity_timeout = 2 * ed
29
- rescue Exception => ex
30
- logger.error "Exception setting up transceiver: #{ex} at #{ex.backtrace.join("\n")}"
31
- raise
32
- end
33
-
34
16
  # Send an MT SMS message. Delegate will receive message_accepted callback when SMSC
35
17
  # acknowledges, or the message_rejected callback upon error
36
18
  def send_mt(message_id, source_addr, destination_addr, short_message, options={})
@@ -54,21 +36,22 @@ class Smpp::Transceiver < Smpp::Base
54
36
  # Split the message into parts of 153 characters. (160 - 7 characters for UDH)
55
37
  parts = []
56
38
  while message.size > 0 do
57
- parts << message.slice!(0..152)
39
+ parts << message.slice!(0..Smpp::Transceiver.get_message_part_size(options))
58
40
  end
59
41
 
60
42
  0.upto(parts.size-1) do |i|
61
43
  udh = sprintf("%c", 5) # UDH is 5 bytes.
62
44
  udh << sprintf("%c%c", 0, 3) # This is a concatenated message
45
+
46
+ #TODO Figure out why this needs to be an int here, it's a string elsewhere
63
47
  udh << sprintf("%c", message_id) # The ID for the entire concatenated message
48
+
64
49
  udh << sprintf("%c", parts.size) # How many parts this message consists of
65
50
  udh << sprintf("%c", i+1) # This is part i+1
66
51
 
67
- options = {
68
- :esm_class => 64, # This message contains a UDH header.
69
- :udh => udh
70
- }
71
-
52
+ options[:esm_class] = 64 # This message contains a UDH header.
53
+ options[:udh] = udh
54
+
72
55
  pdu = Pdu::SubmitSm.new(source_addr, destination_addr, parts[i], options)
73
56
  write_pdu pdu
74
57
 
@@ -98,82 +81,6 @@ class Smpp::Transceiver < Smpp::Base
98
81
  end
99
82
  end
100
83
 
101
- # a PDU is received. Parse it and invoke delegate methods.
102
- def process_pdu(pdu)
103
- case pdu
104
- when Pdu::DeliverSm
105
- write_pdu(Pdu::DeliverSmResponse.new(pdu.sequence_number))
106
- logger.debug "ESM CLASS #{pdu.esm_class}"
107
- if pdu.esm_class != 4
108
- # MO message
109
- if @delegate.respond_to?(:mo_received)
110
- @delegate.mo_received(self, pdu)
111
- end
112
- else
113
- # Delivery report
114
- if @delegate.respond_to?(:delivery_report_received)
115
- @delegate.delivery_report_received(self, pdu)
116
- end
117
- end
118
- when Pdu::BindTransceiverResponse
119
- case pdu.command_status
120
- when Pdu::Base::ESME_ROK
121
- logger.debug "Bound OK."
122
- @state = :bound
123
- if @delegate.respond_to?(:bound)
124
- @delegate.bound(self)
125
- end
126
- when Pdu::Base::ESME_RINVPASWD
127
- logger.warn "Invalid password."
128
- # scheduele the connection to close, which eventually will cause the unbound() delegate
129
- # method to be invoked.
130
- close_connection
131
- when Pdu::Base::ESME_RINVSYSID
132
- logger.warn "Invalid system id."
133
- close_connection
134
- else
135
- logger.warn "Unexpected BindTransceiverResponse. Command status: #{pdu.command_status}"
136
- close_connection
137
- end
138
- when Pdu::SubmitSmResponse
139
- mt_message_id = @ack_ids.delete(pdu.sequence_number)
140
- if !mt_message_id
141
- raise "Got SubmitSmResponse for unknown sequence_number: #{pdu.sequence_number}"
142
- end
143
- if pdu.command_status != Pdu::Base::ESME_ROK
144
- logger.error "Error status in SubmitSmResponse: #{pdu.command_status}"
145
- if @delegate.respond_to?(:message_rejected)
146
- @delegate.message_rejected(self, mt_message_id, pdu)
147
- end
148
- else
149
- logger.info "Got OK SubmitSmResponse (#{pdu.message_id} -> #{mt_message_id})"
150
- if @delegate.respond_to?(:message_accepted)
151
- @delegate.message_accepted(self, mt_message_id, pdu)
152
- end
153
- end
154
- # Now we got the SMSC message id; create pending delivery report.
155
- @pdr_storage[pdu.message_id] = mt_message_id
156
- when Pdu::SubmitMultiResponse
157
- mt_message_id = @ack_ids[pdu.sequence_number]
158
- if !mt_message_id
159
- raise "Got SubmitMultiResponse for unknown sequence_number: #{pdu.sequence_number}"
160
- end
161
- if pdu.command_status != Pdu::Base::ESME_ROK
162
- logger.error "Error status in SubmitMultiResponse: #{pdu.command_status}"
163
- if @delegate.respond_to?(:message_rejected)
164
- @delegate.message_rejected(self, mt_message_id, pdu)
165
- end
166
- else
167
- logger.info "Got OK SubmitMultiResponse (#{pdu.message_id} -> #{mt_message_id})"
168
- if @delegate.respond_to?(:message_accepted)
169
- @delegate.message_accepted(self, mt_message_id, pdu)
170
- end
171
- end
172
- else
173
- super
174
- end
175
- end
176
-
177
84
  # Send BindTransceiverResponse PDU.
178
85
  def send_bind
179
86
  raise IOError, 'Receiver already bound.' unless unbound?
@@ -186,4 +93,17 @@ class Smpp::Transceiver < Smpp::Base
186
93
  @config[:source_address_range])
187
94
  write_pdu(pdu)
188
95
  end
96
+
97
+ # Use data_coding to find out what message part size we can use
98
+ # http://en.wikipedia.org/wiki/SMS#Message_size
99
+ def self.get_message_part_size options
100
+ return 153 if options[:data_coding].nil?
101
+ return 153 if options[:data_coding] == 0
102
+ return 134 if options[:data_coding] == 3
103
+ return 134 if options[:data_coding] == 5
104
+ return 134 if options[:data_coding] == 6
105
+ return 134 if options[:data_coding] == 7
106
+ return 67 if options[:data_coding] == 8
107
+ return 153
108
+ end
189
109
  end
data/ruby-smpp.gemspec CHANGED
@@ -1,101 +1,112 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruby-smpp}
8
- s.version = "0.4.0"
8
+ s.version = "0.5.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{2011-01-06}
12
+ s.date = %q{2011-04-16}
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 = [
16
16
  "CHANGELOG",
17
- "CONTRIBUTORS.txt",
18
- "README.rdoc"
17
+ "CONTRIBUTORS.txt",
18
+ "README.rdoc"
19
19
  ]
20
20
  s.files = [
21
- ".gitignore",
22
- "CHANGELOG",
23
- "CONTRIBUTORS.txt",
24
- "Gemfile",
25
- "Gemfile.lock",
26
- "LICENSE",
27
- "README.rdoc",
28
- "Rakefile",
29
- "VERSION",
30
- "config/environment.rb",
31
- "examples/PDU1.example",
32
- "examples/PDU2.example",
33
- "examples/sample_gateway.rb",
34
- "examples/sample_smsc.rb",
35
- "lib/smpp.rb",
36
- "lib/smpp/base.rb",
37
- "lib/smpp/optional_parameter.rb",
38
- "lib/smpp/pdu/base.rb",
39
- "lib/smpp/pdu/bind_base.rb",
40
- "lib/smpp/pdu/bind_receiver.rb",
41
- "lib/smpp/pdu/bind_receiver_response.rb",
42
- "lib/smpp/pdu/bind_resp_base.rb",
43
- "lib/smpp/pdu/bind_transceiver.rb",
44
- "lib/smpp/pdu/bind_transceiver_response.rb",
45
- "lib/smpp/pdu/deliver_sm.rb",
46
- "lib/smpp/pdu/deliver_sm_response.rb",
47
- "lib/smpp/pdu/enquire_link.rb",
48
- "lib/smpp/pdu/enquire_link_response.rb",
49
- "lib/smpp/pdu/generic_nack.rb",
50
- "lib/smpp/pdu/submit_multi.rb",
51
- "lib/smpp/pdu/submit_multi_response.rb",
52
- "lib/smpp/pdu/submit_sm.rb",
53
- "lib/smpp/pdu/submit_sm_response.rb",
54
- "lib/smpp/pdu/unbind.rb",
55
- "lib/smpp/pdu/unbind_response.rb",
56
- "lib/smpp/receiver.rb",
57
- "lib/smpp/server.rb",
58
- "lib/smpp/transceiver.rb",
59
- "lib/sms.rb",
60
- "ruby-smpp.gemspec",
61
- "test/delegate.rb",
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",
67
- "test/smpp_test.rb",
68
- "test/submit_sm_test.rb"
21
+ "CHANGELOG",
22
+ "CONTRIBUTORS.txt",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "config/environment.rb",
30
+ "examples/PDU1.example",
31
+ "examples/PDU2.example",
32
+ "examples/sample_gateway.rb",
33
+ "examples/sample_smsc.rb",
34
+ "lib/smpp.rb",
35
+ "lib/smpp/base.rb",
36
+ "lib/smpp/encoding/utf8_encoder.rb",
37
+ "lib/smpp/optional_parameter.rb",
38
+ "lib/smpp/pdu/base.rb",
39
+ "lib/smpp/pdu/bind_base.rb",
40
+ "lib/smpp/pdu/bind_receiver.rb",
41
+ "lib/smpp/pdu/bind_receiver_response.rb",
42
+ "lib/smpp/pdu/bind_resp_base.rb",
43
+ "lib/smpp/pdu/bind_transceiver.rb",
44
+ "lib/smpp/pdu/bind_transceiver_response.rb",
45
+ "lib/smpp/pdu/deliver_sm.rb",
46
+ "lib/smpp/pdu/deliver_sm_response.rb",
47
+ "lib/smpp/pdu/enquire_link.rb",
48
+ "lib/smpp/pdu/enquire_link_response.rb",
49
+ "lib/smpp/pdu/generic_nack.rb",
50
+ "lib/smpp/pdu/submit_multi.rb",
51
+ "lib/smpp/pdu/submit_multi_response.rb",
52
+ "lib/smpp/pdu/submit_sm.rb",
53
+ "lib/smpp/pdu/submit_sm_response.rb",
54
+ "lib/smpp/pdu/unbind.rb",
55
+ "lib/smpp/pdu/unbind_response.rb",
56
+ "lib/smpp/receiver.rb",
57
+ "lib/smpp/server.rb",
58
+ "lib/smpp/transceiver.rb",
59
+ "lib/sms.rb",
60
+ "ruby-smpp.gemspec",
61
+ "test/delegate.rb",
62
+ "test/encoding_test.rb",
63
+ "test/optional_parameter_test.rb",
64
+ "test/pdu_parsing_test.rb",
65
+ "test/receiver_test.rb",
66
+ "test/responsive_delegate.rb",
67
+ "test/server.rb",
68
+ "test/smpp_test.rb",
69
+ "test/submit_sm_test.rb",
70
+ "test/transceiver_test.rb"
69
71
  ]
70
72
  s.homepage = %q{http://github.com/raykrueger/ruby-smpp}
71
- s.rdoc_options = ["--charset=UTF-8"]
72
73
  s.require_paths = ["lib"]
73
74
  s.rubyforge_project = %q{ruby-smpp}
74
- s.rubygems_version = %q{1.3.6}
75
+ s.rubygems_version = %q{1.5.3}
75
76
  s.summary = %q{Ruby implementation of the SMPP protocol, based on EventMachine.}
76
77
  s.test_files = [
78
+ "examples/sample_gateway.rb",
79
+ "examples/sample_smsc.rb",
77
80
  "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",
83
- "test/smpp_test.rb",
84
- "test/submit_sm_test.rb",
85
- "examples/sample_gateway.rb",
86
- "examples/sample_smsc.rb"
81
+ "test/encoding_test.rb",
82
+ "test/optional_parameter_test.rb",
83
+ "test/pdu_parsing_test.rb",
84
+ "test/receiver_test.rb",
85
+ "test/responsive_delegate.rb",
86
+ "test/server.rb",
87
+ "test/smpp_test.rb",
88
+ "test/submit_sm_test.rb",
89
+ "test/transceiver_test.rb"
87
90
  ]
88
91
 
89
92
  if s.respond_to? :specification_version then
90
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
91
93
  s.specification_version = 3
92
94
 
93
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
95
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
96
+ s.add_runtime_dependency(%q<jeweler>, [">= 0"])
97
+ s.add_runtime_dependency(%q<rake>, [">= 0"])
98
+ s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
94
99
  s.add_runtime_dependency(%q<eventmachine>, [">= 0.10.0"])
95
100
  else
101
+ s.add_dependency(%q<jeweler>, [">= 0"])
102
+ s.add_dependency(%q<rake>, [">= 0"])
103
+ s.add_dependency(%q<eventmachine>, [">= 0"])
96
104
  s.add_dependency(%q<eventmachine>, [">= 0.10.0"])
97
105
  end
98
106
  else
107
+ s.add_dependency(%q<jeweler>, [">= 0"])
108
+ s.add_dependency(%q<rake>, [">= 0"])
109
+ s.add_dependency(%q<eventmachine>, [">= 0"])
99
110
  s.add_dependency(%q<eventmachine>, [">= 0.10.0"])
100
111
  end
101
112
  end
@@ -0,0 +1,231 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'smpp/encoding/utf8_encoder'
4
+
5
+ require File.expand_path(File.dirname(__FILE__) + "../../lib/smpp")
6
+
7
+ class EncodingTest < Test::Unit::TestCase
8
+
9
+
10
+ def setup
11
+ ::Smpp::Pdu::DeliverSm.data_encoder = ::Smpp::Encoding::Utf8Encoder.new
12
+ end
13
+
14
+ def teardown
15
+ ::Smpp::Pdu::DeliverSm.data_encoder = nil
16
+ end
17
+
18
+ def test_should_decode_pound_sign_from_hp_roman_8_to_utf_8
19
+ raw_data = <<-EOF
20
+ 0000 003d 0000 0005 0000 0000 0000 0002
21
+ 0001 0134 3437 3830 3330 3239 3833 3700
22
+ 0101 3434 3738 3033 3032 3938 3337 0000
23
+ 0000 0000 0000 0000 2950 6C65 6173 6520
24
+ 6465 706F 7369 7420 BB35 2069 6E74 6F20
25
+ 6D79 2061 6363 6F75 6E74 2C20 4A6F 73C5
26
+ EOF
27
+
28
+ pdu = create_pdu(raw_data)
29
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
30
+ assert_equal 0, pdu.data_coding
31
+
32
+ expected = "Please deposit \302\2435 into my account, Jos\303\251"
33
+ assert_equal expected, pdu.short_message
34
+ end
35
+
36
+ def test_should_unescape_gsm_escaped_euro_symbol
37
+ raw_data = <<-EOF
38
+ 0000 003d 0000 0005 0000 0000 0000 0002
39
+ 0001 0134 3437 3830 3330 3239 3833 3700
40
+ 0101 3434 3738 3033 3032 3938 3337 0000
41
+ 0000 0000 0000 0000 1950 6c65 6173 6520
42
+ 6465 706f 7369 7420 8d65 3520 7468 616e
43
+ 6b73
44
+ EOF
45
+
46
+ pdu = create_pdu(raw_data)
47
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
48
+ assert_equal 0, pdu.data_coding
49
+
50
+ expected = "Please deposit \342\202\2545 thanks"
51
+ assert_equal expected, pdu.short_message
52
+ end
53
+
54
+ def test_should_unescape_gsm_escaped_left_curly_bracket_symbol
55
+ raw_data = <<-EOF
56
+ 0000 003d 0000 0005 0000 0000 0000 0002
57
+ 0001 0134 3437 3830 3330 3239 3833 3700
58
+ 0101 3434 3738 3033 3032 3938 3337 0000
59
+ 0000 0000 0000 0000 028d 28
60
+ EOF
61
+
62
+ pdu = create_pdu(raw_data)
63
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
64
+ assert_equal 0, pdu.data_coding
65
+
66
+ assert_equal "{", pdu.short_message
67
+ end
68
+
69
+ def test_should_unescape_gsm_escaped_right_curly_bracket_symbol
70
+ raw_data = <<-EOF
71
+ 0000 003d 0000 0005 0000 0000 0000 0002
72
+ 0001 0134 3437 3830 3330 3239 3833 3700
73
+ 0101 3434 3738 3033 3032 3938 3337 0000
74
+ 0000 0000 0000 0000 028d 29
75
+ EOF
76
+
77
+ pdu = create_pdu(raw_data)
78
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
79
+ assert_equal 0, pdu.data_coding
80
+
81
+ assert_equal "}", pdu.short_message
82
+ end
83
+
84
+ def test_should_unescape_gsm_escaped_tilde_symbol
85
+ raw_data = <<-EOF
86
+ 0000 003d 0000 0005 0000 0000 0000 0002
87
+ 0001 0134 3437 3830 3330 3239 3833 3700
88
+ 0101 3434 3738 3033 3032 3938 3337 0000
89
+ 0000 0000 0000 0000 028d 3d
90
+ EOF
91
+
92
+ pdu = create_pdu(raw_data)
93
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
94
+ assert_equal 0, pdu.data_coding
95
+
96
+ assert_equal "~", pdu.short_message
97
+ end
98
+
99
+ def test_should_unescape_gsm_escaped_left_square_bracket_symbol
100
+ raw_data = <<-EOF
101
+ 0000 003d 0000 0005 0000 0000 0000 0002
102
+ 0001 0134 3437 3830 3330 3239 3833 3700
103
+ 0101 3434 3738 3033 3032 3938 3337 0000
104
+ 0000 0000 0000 0000 028d 3c
105
+ EOF
106
+
107
+ pdu = create_pdu(raw_data)
108
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
109
+ assert_equal 0, pdu.data_coding
110
+
111
+ assert_equal "[", pdu.short_message
112
+ end
113
+
114
+ def test_should_unescape_gsm_escaped_right_square_bracket_symbol
115
+ raw_data = <<-EOF
116
+ 0000 003d 0000 0005 0000 0000 0000 0002
117
+ 0001 0134 3437 3830 3330 3239 3833 3700
118
+ 0101 3434 3738 3033 3032 3938 3337 0000
119
+ 0000 0000 0000 0000 028d 3e
120
+ EOF
121
+
122
+ pdu = create_pdu(raw_data)
123
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
124
+ assert_equal 0, pdu.data_coding
125
+
126
+ assert_equal "]", pdu.short_message
127
+ end
128
+
129
+ def test_should_unescape_gsm_escaped_backslash_symbol
130
+ raw_data = <<-EOF
131
+ 0000 003d 0000 0005 0000 0000 0000 0002
132
+ 0001 0134 3437 3830 3330 3239 3833 3700
133
+ 0101 3434 3738 3033 3032 3938 3337 0000
134
+ 0000 0000 0000 0000 028d 2f
135
+ EOF
136
+
137
+ pdu = create_pdu(raw_data)
138
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
139
+ assert_equal 0, pdu.data_coding
140
+
141
+ assert_equal "\\", pdu.short_message
142
+ end
143
+
144
+ def test_should_unescape_gsm_escaped_vertical_bar_symbol
145
+ raw_data = <<-EOF
146
+ 0000 003d 0000 0005 0000 0000 0000 0002
147
+ 0001 0134 3437 3830 3330 3239 3833 3700
148
+ 0101 3434 3738 3033 3032 3938 3337 0000
149
+ 0000 0000 0000 0000 028d b8
150
+ EOF
151
+
152
+ pdu = create_pdu(raw_data)
153
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
154
+ assert_equal 0, pdu.data_coding
155
+
156
+ assert_equal "|", pdu.short_message
157
+ end
158
+
159
+ def test_should_unescape_gsm_escaped_caret_or_circumflex_symbol
160
+ raw_data = <<-EOF
161
+ 0000 003d 0000 0005 0000 0000 0000 0002
162
+ 0001 0134 3437 3830 3330 3239 3833 3700
163
+ 0101 3434 3738 3033 3032 3938 3337 0000
164
+ 0000 0000 0000 0000 028d 86
165
+ EOF
166
+
167
+ pdu = create_pdu(raw_data)
168
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
169
+ assert_equal 0, pdu.data_coding
170
+
171
+ expected = "\313\206"
172
+ assert_equal expected, pdu.short_message
173
+ end
174
+
175
+ def test_should_unescape_gsm_escaped_characters_together
176
+ raw_data = <<-EOF
177
+ 0000 003d 0000 0005 0000 0000 0000 0002
178
+ 0001 0134 3437 3830 3330 3239 3833 3700
179
+ 0101 3434 3738 3033 3032 3938 3337 0000
180
+ 0000 0000 0000 0000 4054 6573 748d b869
181
+ 6e67 208d 8620 7374 6167 2f69 6e67 208d
182
+ 3d20 6575 726f 208d 6520 616e 6420 8d28
183
+ 6f74 688d 2f65 7220 8d3c 2063 6861 7261
184
+ 8d3e 6374 6572 738d 29
185
+ EOF
186
+
187
+ pdu = create_pdu(raw_data)
188
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
189
+ assert_equal 0, pdu.data_coding
190
+
191
+ expected = "Test|ing ˆ stag/ing ~ euro € and {oth\\er [ chara]cters}"
192
+ assert_equal expected, pdu.short_message
193
+ end
194
+
195
+ def test_should_convert_ucs_2_into_utf_8_where_data_coding_indicates_its_presence
196
+ raw_data = <<-EOF
197
+ 0000 003d 0000 0005 0000 0000 0000 0002
198
+ 0001 0134 3437 3830 3330 3239 3833 3700
199
+ 0101 3434 3738 3033 3032 3938 3337 0000
200
+ 0000 0000 0000 0800 0E00 db00 f100 ef00
201
+ e700 f800 6401 13
202
+ EOF
203
+
204
+ pdu = create_pdu(raw_data)
205
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
206
+ assert_equal 8, pdu.data_coding
207
+
208
+ expected = "\303\233\303\261\303\257\303\247\303\270d\304\223" # Ûñïçødē
209
+ assert_equal expected, pdu.short_message
210
+ end
211
+
212
+ def test_should_decode_pound_sign_from_hp_roman_8_to_utf_8_when_data_coding_set_to_1
213
+ raw_data = <<-EOF
214
+ 0000 0096 0000 0005 0000 0000 0000 1b10
215
+ 0005 004d 6f6e 6579 416c 6572 7400 0101
216
+ 3434 3737 3738 3030 3036 3133 0000 0000
217
+ 0000 0000 0100 5fbb 506f 756e 6473 bb20
218
+ EOF
219
+
220
+ pdu = create_pdu(raw_data)
221
+ assert_equal Smpp::Pdu::DeliverSm, pdu.class
222
+ assert_equal "£Pounds£ ", pdu.short_message
223
+ end
224
+
225
+ protected
226
+ def create_pdu(raw_data)
227
+ hex_data = [raw_data.chomp.gsub(" ","").gsub(/\n/,"")].pack("H*")
228
+ Smpp::Pdu::Base.create(hex_data)
229
+ end
230
+
231
+ end
@@ -75,10 +75,37 @@ class PduParsingTest < Test::Unit::TestCase
75
75
  assert_equal " and provide a good user experience", pdu.short_message
76
76
  end
77
77
 
78
+ def test_submit_sm_response_clean
79
+ data = <<-EOF
80
+ 0000 0028 8000 0004 0000 0000 4da8 ebed
81
+ 3534 3131 342d 3034 3135 562d 3231 3230
82
+ 452d 3039 4831 5100
83
+ EOF
84
+
85
+ pdu = create_pdu(data)
86
+ assert_equal Smpp::Pdu::SubmitSmResponse, pdu.class
87
+ assert_equal "54114-0415V-2120E-09H1Q", pdu.message_id
88
+ end
89
+
90
+ def test_submit_sm_response_with_optional_params
91
+ data = <<-EOF
92
+ 0000 0031 8000 0004 0000 042e 4da8 e9a1
93
+ 0021 5300 0201 7721 6700 1653 6f75 7263
94
+ 6520 6164 6472 6573 7320 6465 6e69 6564
95
+ 2e
96
+ EOF
97
+
98
+ pdu = create_pdu(data)
99
+ assert_equal Smpp::Pdu::SubmitSmResponse, pdu.class
100
+ assert_equal "", pdu.message_id
101
+ assert pdu.optional_parameters
102
+ assert_equal "Source address denied.", pdu.optional_parameter(0x2167)
103
+ end
104
+
78
105
  protected
79
106
  def create_pdu(raw_data)
80
- hex_data = [raw_data.chomp.gsub(" ","").gsub(/\n/,"")].pack("H*")
107
+ hex_data = [raw_data.chomp.gsub(/\s/,"")].pack("H*")
81
108
  Smpp::Pdu::Base.create(hex_data)
82
109
  end
83
110
 
84
- end
111
+ end
@@ -20,6 +20,12 @@ class ReceiverTest < Test::Unit::TestCase
20
20
  end
21
21
  end
22
22
 
23
+ class ExceptionRaisingDelegate < RecordingDelegate
24
+ def mo_received(receiver, pdu)
25
+ raise "exception in delegate"
26
+ end
27
+ end
28
+
23
29
  def test_receiving_bind_receiver_response_with_ok_status_should_become_bound
24
30
  receiver = build_receiver
25
31
  bind_receiver_response = Smpp::Pdu::BindReceiverResponse.new(nil, Smpp::Pdu::Base::ESME_ROK, 1)
@@ -76,7 +82,36 @@ class ReceiverTest < Test::Unit::TestCase
76
82
  end
77
83
 
78
84
  def test_receiving_deliver_sm_should_send_deliver_sm_response
79
- receiver = build_receiver
85
+ delegate = RecordingDelegate.new
86
+ receiver = build_receiver(delegate)
87
+ deliver_sm = Smpp::Pdu::DeliverSm.new("from", "to", "message")
88
+
89
+ receiver.process_pdu(deliver_sm)
90
+
91
+ first_sent_data = receiver.sent_data.first
92
+ assert_not_nil first_sent_data
93
+ actual_response = Smpp::Pdu::Base.create(first_sent_data)
94
+ expected_response = Smpp::Pdu::DeliverSmResponse.new(deliver_sm.sequence_number)
95
+ assert_equal expected_response.to_human, actual_response.to_human
96
+ end
97
+
98
+ def test_receiving_deliver_sm_should_send_error_response_if_delegate_raises_exception
99
+ delegate = ExceptionRaisingDelegate.new
100
+ receiver = build_receiver(delegate)
101
+ deliver_sm = Smpp::Pdu::DeliverSm.new("from", "to", "message")
102
+
103
+ receiver.process_pdu(deliver_sm)
104
+
105
+ first_sent_data = receiver.sent_data.first
106
+ assert_not_nil first_sent_data
107
+ actual_response = Smpp::Pdu::Base.create(first_sent_data)
108
+ expected_response = Smpp::Pdu::DeliverSmResponse.new(deliver_sm.sequence_number, Smpp::Pdu::Base::ESME_RX_T_APPN)
109
+ assert_equal expected_response.to_human, actual_response.to_human
110
+ end
111
+
112
+ def test_receiving_deliver_sm_should_still_send_deliver_sm_response_when_no_delegate_is_provided
113
+ delegate = nil
114
+ receiver = build_receiver(delegate)
80
115
  deliver_sm = Smpp::Pdu::DeliverSm.new("from", "to", "message")
81
116
 
82
117
  receiver.process_pdu(deliver_sm)
@@ -0,0 +1,35 @@
1
+ require "rubygems"
2
+ require "test/unit"
3
+ require File.expand_path(File.dirname(__FILE__) + "../../lib/smpp")
4
+
5
+ class TransceiverTest < Test::Unit::TestCase
6
+ def test_get_message_part_size_8
7
+ options = {:data_coding => 8}
8
+ assert_equal(67, Smpp::Transceiver.get_message_part_size(options))
9
+ end
10
+ def test_get_message_part_size_0_and_1
11
+ options = {:data_coding => 0}
12
+ assert_equal(153, Smpp::Transceiver.get_message_part_size(options))
13
+ options = {:data_coding => 1}
14
+ assert_equal(153, Smpp::Transceiver.get_message_part_size(options))
15
+ end
16
+ def test_get_message_part_size_nil
17
+ options = {}
18
+ assert_equal(153, Smpp::Transceiver.get_message_part_size(options))
19
+ end
20
+ def test_get_message_part_size_other
21
+ options = {:data_coding => 3}
22
+ assert_equal(134, Smpp::Transceiver.get_message_part_size(options))
23
+ options = {:data_coding => 5}
24
+ assert_equal(134, Smpp::Transceiver.get_message_part_size(options))
25
+ options = {:data_coding => 6}
26
+ assert_equal(134, Smpp::Transceiver.get_message_part_size(options))
27
+ options = {:data_coding => 7}
28
+ assert_equal(134, Smpp::Transceiver.get_message_part_size(options))
29
+ end
30
+ def test_get_message_part_size_non_existant_data_coding
31
+ options = {:data_coding => 666}
32
+ assert_equal(153, Smpp::Transceiver.get_message_part_size(options))
33
+ end
34
+ end
35
+
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-smpp
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 11
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
- - 4
8
+ - 5
8
9
  - 0
9
- version: 0.4.0
10
+ version: 0.5.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Ray Krueger
@@ -15,23 +16,67 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-01-06 00:00:00 -06:00
19
+ date: 2011-04-16 00:00:00 -05:00
19
20
  default_executable:
20
21
  dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: jeweler
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ prerelease: false
34
+ type: :runtime
35
+ requirement: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ prerelease: false
48
+ type: :runtime
49
+ requirement: *id002
21
50
  - !ruby/object:Gem::Dependency
22
51
  name: eventmachine
52
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ prerelease: false
23
62
  type: :runtime
24
- version_requirements: &id001 !ruby/object:Gem::Requirement
63
+ requirement: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: eventmachine
66
+ version_requirements: &id004 !ruby/object:Gem::Requirement
67
+ none: false
25
68
  requirements:
26
69
  - - ">="
27
70
  - !ruby/object:Gem::Version
71
+ hash: 55
28
72
  segments:
29
73
  - 0
30
74
  - 10
31
75
  - 0
32
76
  version: 0.10.0
33
77
  prerelease: false
34
- requirement: *id001
78
+ type: :runtime
79
+ requirement: *id004
35
80
  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
81
  email: raykrueger@gmail.com
37
82
  executables: []
@@ -43,7 +88,6 @@ extra_rdoc_files:
43
88
  - CONTRIBUTORS.txt
44
89
  - README.rdoc
45
90
  files:
46
- - .gitignore
47
91
  - CHANGELOG
48
92
  - CONTRIBUTORS.txt
49
93
  - Gemfile
@@ -59,6 +103,7 @@ files:
59
103
  - examples/sample_smsc.rb
60
104
  - lib/smpp.rb
61
105
  - lib/smpp/base.rb
106
+ - lib/smpp/encoding/utf8_encoder.rb
62
107
  - lib/smpp/optional_parameter.rb
63
108
  - lib/smpp/pdu/base.rb
64
109
  - lib/smpp/pdu/bind_base.rb
@@ -84,6 +129,7 @@ files:
84
129
  - lib/sms.rb
85
130
  - ruby-smpp.gemspec
86
131
  - test/delegate.rb
132
+ - test/encoding_test.rb
87
133
  - test/optional_parameter_test.rb
88
134
  - test/pdu_parsing_test.rb
89
135
  - test/receiver_test.rb
@@ -91,38 +137,46 @@ files:
91
137
  - test/server.rb
92
138
  - test/smpp_test.rb
93
139
  - test/submit_sm_test.rb
140
+ - test/transceiver_test.rb
94
141
  has_rdoc: true
95
142
  homepage: http://github.com/raykrueger/ruby-smpp
96
143
  licenses: []
97
144
 
98
145
  post_install_message:
99
- rdoc_options:
100
- - --charset=UTF-8
146
+ rdoc_options: []
147
+
101
148
  require_paths:
102
149
  - lib
103
150
  required_ruby_version: !ruby/object:Gem::Requirement
151
+ none: false
104
152
  requirements:
105
153
  - - ">="
106
154
  - !ruby/object:Gem::Version
155
+ hash: 3
107
156
  segments:
108
157
  - 0
109
158
  version: "0"
110
159
  required_rubygems_version: !ruby/object:Gem::Requirement
160
+ none: false
111
161
  requirements:
112
162
  - - ">="
113
163
  - !ruby/object:Gem::Version
164
+ hash: 3
114
165
  segments:
115
166
  - 0
116
167
  version: "0"
117
168
  requirements: []
118
169
 
119
170
  rubyforge_project: ruby-smpp
120
- rubygems_version: 1.3.6
171
+ rubygems_version: 1.5.3
121
172
  signing_key:
122
173
  specification_version: 3
123
174
  summary: Ruby implementation of the SMPP protocol, based on EventMachine.
124
175
  test_files:
176
+ - examples/sample_gateway.rb
177
+ - examples/sample_smsc.rb
125
178
  - test/delegate.rb
179
+ - test/encoding_test.rb
126
180
  - test/optional_parameter_test.rb
127
181
  - test/pdu_parsing_test.rb
128
182
  - test/receiver_test.rb
@@ -130,5 +184,4 @@ test_files:
130
184
  - test/server.rb
131
185
  - test/smpp_test.rb
132
186
  - test/submit_sm_test.rb
133
- - examples/sample_gateway.rb
134
- - examples/sample_smsc.rb
187
+ - test/transceiver_test.rb
data/.gitignore DELETED
@@ -1,24 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
- tags
21
-
22
- ## PROJECT::SPECIFIC
23
- *.log
24
- nbproject