anjlab-ruby-smpp 0.6.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.
Files changed (51) hide show
  1. data/CHANGELOG +52 -0
  2. data/CONTRIBUTORS.txt +11 -0
  3. data/Gemfile +8 -0
  4. data/Gemfile.lock +18 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +89 -0
  7. data/Rakefile +53 -0
  8. data/VERSION +1 -0
  9. data/config/environment.rb +2 -0
  10. data/examples/PDU1.example +26 -0
  11. data/examples/PDU2.example +26 -0
  12. data/examples/sample_gateway.rb +137 -0
  13. data/examples/sample_smsc.rb +102 -0
  14. data/lib/smpp.rb +25 -0
  15. data/lib/smpp/base.rb +308 -0
  16. data/lib/smpp/encoding/utf8_encoder.rb +37 -0
  17. data/lib/smpp/optional_parameter.rb +35 -0
  18. data/lib/smpp/pdu/base.rb +183 -0
  19. data/lib/smpp/pdu/bind_base.rb +25 -0
  20. data/lib/smpp/pdu/bind_receiver.rb +4 -0
  21. data/lib/smpp/pdu/bind_receiver_response.rb +4 -0
  22. data/lib/smpp/pdu/bind_resp_base.rb +17 -0
  23. data/lib/smpp/pdu/bind_transceiver.rb +4 -0
  24. data/lib/smpp/pdu/bind_transceiver_response.rb +4 -0
  25. data/lib/smpp/pdu/deliver_sm.rb +142 -0
  26. data/lib/smpp/pdu/deliver_sm_response.rb +12 -0
  27. data/lib/smpp/pdu/enquire_link.rb +11 -0
  28. data/lib/smpp/pdu/enquire_link_response.rb +11 -0
  29. data/lib/smpp/pdu/generic_nack.rb +20 -0
  30. data/lib/smpp/pdu/submit_multi.rb +68 -0
  31. data/lib/smpp/pdu/submit_multi_response.rb +49 -0
  32. data/lib/smpp/pdu/submit_sm.rb +91 -0
  33. data/lib/smpp/pdu/submit_sm_response.rb +31 -0
  34. data/lib/smpp/pdu/unbind.rb +11 -0
  35. data/lib/smpp/pdu/unbind_response.rb +12 -0
  36. data/lib/smpp/receiver.rb +27 -0
  37. data/lib/smpp/server.rb +223 -0
  38. data/lib/smpp/transceiver.rb +109 -0
  39. data/lib/sms.rb +9 -0
  40. data/ruby-smpp.gemspec +96 -0
  41. data/test/delegate.rb +28 -0
  42. data/test/encoding_test.rb +231 -0
  43. data/test/optional_parameter_test.rb +30 -0
  44. data/test/pdu_parsing_test.rb +111 -0
  45. data/test/receiver_test.rb +232 -0
  46. data/test/responsive_delegate.rb +53 -0
  47. data/test/server.rb +56 -0
  48. data/test/smpp_test.rb +239 -0
  49. data/test/submit_sm_test.rb +40 -0
  50. data/test/transceiver_test.rb +35 -0
  51. metadata +133 -0
@@ -0,0 +1,109 @@
1
+ # The SMPP Transceiver maintains a bidirectional connection to an SMSC.
2
+ # Provide a config hash with connection options to get started.
3
+ # See the sample_gateway.rb for examples of config values.
4
+ # The transceiver accepts a delegate object that may implement
5
+ # the following (all optional) methods:
6
+ #
7
+ # mo_received(transceiver, pdu)
8
+ # delivery_report_received(transceiver, pdu)
9
+ # message_accepted(transceiver, mt_message_id, pdu)
10
+ # message_rejected(transceiver, mt_message_id, pdu)
11
+ # bound(transceiver)
12
+ # unbound(transceiver)
13
+
14
+ class Smpp::Transceiver < Smpp::Base
15
+
16
+ # Send an MT SMS message. Delegate will receive message_accepted callback when SMSC
17
+ # acknowledges, or the message_rejected callback upon error
18
+ def send_mt(message_id, source_addr, destination_addr, short_message, options={})
19
+ logger.debug "Sending MT: #{short_message}"
20
+ if @state == :bound
21
+ pdu = Pdu::SubmitSm.new(source_addr, destination_addr, short_message, options)
22
+ write_pdu pdu
23
+
24
+ # keep the message ID so we can associate the SMSC message ID with our message
25
+ # when the response arrives.
26
+ @ack_ids[pdu.sequence_number] = message_id
27
+ else
28
+ raise InvalidStateException, "Transceiver is unbound. Cannot send MT messages."
29
+ end
30
+ end
31
+
32
+ # Send a concatenated message with a body of > 160 characters as multiple messages.
33
+ def send_concat_mt(message_id, source_addr, destination_addr, message, options = {})
34
+ logger.debug "Sending concatenated MT: #{message}"
35
+ if @state == :bound
36
+ # Split the message into parts of 153 characters. (160 - 7 characters for UDH)
37
+ parts = []
38
+ while message.size > 0 do
39
+ parts << message.slice!(0..Smpp::Transceiver.get_message_part_size(options))
40
+ end
41
+
42
+ 0.upto(parts.size-1) do |i|
43
+ udh = sprintf("%c", 5) # UDH is 5 bytes.
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
47
+ udh << sprintf("%c", message_id) # The ID for the entire concatenated message
48
+
49
+ udh << sprintf("%c", parts.size) # How many parts this message consists of
50
+ udh << sprintf("%c", i+1) # This is part i+1
51
+
52
+ options[:esm_class] = 64 # This message contains a UDH header.
53
+ options[:udh] = udh
54
+
55
+ pdu = Pdu::SubmitSm.new(source_addr, destination_addr, parts[i], options)
56
+ write_pdu pdu
57
+
58
+ # This is definately a bit hacky - multiple PDUs are being associated with a single
59
+ # message_id.
60
+ @ack_ids[pdu.sequence_number] = message_id
61
+ end
62
+ else
63
+ raise InvalidStateException, "Transceiver is unbound. Connot send MT messages."
64
+ end
65
+ end
66
+
67
+ # Send MT SMS message for multiple dest_address
68
+ # Author: Abhishek Parolkar (abhishek[at]parolkar.com)
69
+ # USAGE: $tx.send_multi_mt(123, "9100000000", ["9199000000000","91990000000001","9199000000002"], "Message here")
70
+ def send_multi_mt(message_id, source_addr, destination_addr_arr, short_message, options={})
71
+ logger.debug "Sending Multiple MT: #{short_message}"
72
+ if @state == :bound
73
+ pdu = Pdu::SubmitMulti.new(source_addr, destination_addr_arr, short_message, options)
74
+ write_pdu pdu
75
+
76
+ # keep the message ID so we can associate the SMSC message ID with our message
77
+ # when the response arrives.
78
+ @ack_ids[pdu.sequence_number] = message_id
79
+ else
80
+ raise InvalidStateException, "Transceiver is unbound. Cannot send MT messages."
81
+ end
82
+ end
83
+
84
+ # Send BindTransceiverResponse PDU.
85
+ def send_bind
86
+ raise IOError, 'Receiver already bound.' unless unbound?
87
+ pdu = Pdu::BindTransceiver.new(
88
+ @config[:system_id],
89
+ @config[:password],
90
+ @config[:system_type],
91
+ @config[:source_ton],
92
+ @config[:source_npi],
93
+ @config[:source_address_range])
94
+ write_pdu(pdu)
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
109
+ end
data/lib/sms.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Basic SMS class for sample gateway
2
+
3
+ class Sms
4
+ attr_accessor :id, :from, :to, :body
5
+
6
+ def initialize(body)
7
+ self.body = body
8
+ end
9
+ end
data/ruby-smpp.gemspec ADDED
@@ -0,0 +1,96 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{anjlab-ruby-smpp}
8
+ s.version = "0.6.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ray Krueger", "August Z. Flatby"]
12
+ s.date = %q{2011-10-14}
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
+ s.email = %q{raykrueger@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "CHANGELOG",
17
+ "CONTRIBUTORS.txt",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
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"
71
+ ]
72
+ s.homepage = %q{http://github.com/raykrueger/ruby-smpp}
73
+ s.require_paths = ["lib"]
74
+ s.rubyforge_project = %q{ruby-smpp}
75
+ s.rubygems_version = %q{1.4.2}
76
+ s.summary = %q{Ruby implementation of the SMPP protocol, based on EventMachine.}
77
+
78
+ if s.respond_to? :specification_version then
79
+ s.specification_version = 3
80
+
81
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
82
+ s.add_runtime_dependency(%q<eventmachine>, [">= 0.10.0"])
83
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
84
+ s.add_development_dependency(%q<rake>, [">= 0"])
85
+ else
86
+ s.add_dependency(%q<eventmachine>, [">= 0.10.0"])
87
+ s.add_dependency(%q<jeweler>, [">= 0"])
88
+ s.add_dependency(%q<rake>, [">= 0"])
89
+ end
90
+ else
91
+ s.add_dependency(%q<eventmachine>, [">= 0.10.0"])
92
+ s.add_dependency(%q<jeweler>, [">= 0"])
93
+ s.add_dependency(%q<rake>, [">= 0"])
94
+ end
95
+ end
96
+
data/test/delegate.rb ADDED
@@ -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,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