pdu_sms 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +56 -0
- data/Rakefile +6 -0
- data/bin/console +8 -0
- data/bin/setup +7 -0
- data/lib/pdu_sms.rb +99 -0
- data/lib/pdu_sms/data_coding_scheme.rb +120 -0
- data/lib/pdu_sms/destination_address.rb +57 -0
- data/lib/pdu_sms/helpers.rb +67 -0
- data/lib/pdu_sms/message_reference.rb +41 -0
- data/lib/pdu_sms/originating_address.rb +57 -0
- data/lib/pdu_sms/packet_data_unit.rb +126 -0
- data/lib/pdu_sms/packet_data_unit_error.rb +2 -0
- data/lib/pdu_sms/pdu_type.rb +179 -0
- data/lib/pdu_sms/phone.rb +121 -0
- data/lib/pdu_sms/protocol_identifier.rb +55 -0
- data/lib/pdu_sms/service_center_address.rb +74 -0
- data/lib/pdu_sms/service_center_time_stamp.rb +76 -0
- data/lib/pdu_sms/user_data.rb +276 -0
- data/lib/pdu_sms/user_data_length.rb +81 -0
- data/lib/pdu_sms/validity_period.rb +164 -0
- data/lib/pdu_sms/version.rb +3 -0
- data/pdu_sms.gemspec +25 -0
- metadata +112 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: f34b8435129509cbab1543cb0101fa93e625d775
|
|
4
|
+
data.tar.gz: 43bb228bf0e9b952ce8f429cb80121e34276fac4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 17cb43eacb25768c6a4588528bf873673189625bddcbb962ce0e49e8fef7c78fd280c36b82d1668b40b40d7081f12d11799e85406ce53728c0378741d6ebf22b
|
|
7
|
+
data.tar.gz: d0f1408ac21dad2960554d46c6b3a621f098ce33e2703328ffc85fad1e9c3623b1e6fd6531fa7b435b5a9b8eabb23272fd577546d0762c55b27bc39f5f3601e6
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 Mikhail Stolyarov <schnack.desu@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# PduSms
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
ruby gem 'pdu_sms'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
And then execute:
|
|
13
|
+
|
|
14
|
+
$ bundle
|
|
15
|
+
|
|
16
|
+
Or install it yourself as:
|
|
17
|
+
|
|
18
|
+
$ gem install pdu_sms
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
include PduSms
|
|
23
|
+
# MS(Mobile Station) => SC(SMS Center)
|
|
24
|
+
encode_pdu_ms = PacketDataUnit.encode_ms('+71234567890', 'Hello!!!')
|
|
25
|
+
encode_pdu_ms[0].get_hex #=> "0001000b911732547698F0000008C8329BFD0E8542"
|
|
26
|
+
encode_pdu_ms[0].get_message #=> "Hello!!!"
|
|
27
|
+
encode_pdu_ms[0].get_phone_number #=> "+71234567890"
|
|
28
|
+
|
|
29
|
+
decode_pdu_ms = PacketDataUnit.decode('0001000b911732547698F0000008C8329BFD0E8542')
|
|
30
|
+
decode_pdu_ms.get_hex #=> "0001000b911732547698F0000008C8329BFD0E8542"
|
|
31
|
+
decode_pdu_ms.get_message #=> "Hello!!!"
|
|
32
|
+
decode_pdu_ms.get_phone_number #=> "+71234567890"
|
|
33
|
+
|
|
34
|
+
# SC => MS
|
|
35
|
+
encode_pdu_sc = PacketDataUnit.encode_sc('+71234567890', 'Tele2', 'hello!!!')
|
|
36
|
+
encode_pdu_sc[0].get_hex #=> "07911732547698F00009d0D432BB2C0300005111713115142108E8329BFD0E8542"
|
|
37
|
+
encode_pdu_sc[0].get_message #=> "hello!!!"
|
|
38
|
+
encode_pdu_sc[0].get_phone_number #=> "Tele2"
|
|
39
|
+
|
|
40
|
+
decode_pdu_sc = PacketDataUnit.decode('07911732547698F00009d0D432BB2C0300005111713115142108E8329BFD0E8542')
|
|
41
|
+
decode_pdu_sc.get_hex #=> "07911732547698F00009d0D432BB2C0300005111713115142108E8329BFD0E8542"
|
|
42
|
+
decode_pdu_sc.get_message #=> "hello!!!"
|
|
43
|
+
decode_pdu_sc.get_phone_number #=> "Tele2"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## Contributing
|
|
47
|
+
|
|
48
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/schnack/pdu_sms.
|
|
49
|
+
|
|
50
|
+
## License
|
|
51
|
+
|
|
52
|
+
MTI
|
|
53
|
+
|
|
54
|
+
## Authors
|
|
55
|
+
|
|
56
|
+
* Mikhail Stolyarov <schnack.desu@gmail.com>
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/lib/pdu_sms.rb
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'pdu_sms/helpers'
|
|
2
|
+
require 'pdu_sms/phone'
|
|
3
|
+
require 'pdu_sms/data_coding_scheme'
|
|
4
|
+
require 'pdu_sms/destination_address'
|
|
5
|
+
require 'pdu_sms/message_reference'
|
|
6
|
+
require 'pdu_sms/packet_data_unit'
|
|
7
|
+
require 'pdu_sms/pdu_type'
|
|
8
|
+
require 'pdu_sms/protocol_identifier'
|
|
9
|
+
require 'pdu_sms/service_center_address'
|
|
10
|
+
require 'pdu_sms/user_data'
|
|
11
|
+
require 'pdu_sms/user_data_length'
|
|
12
|
+
require 'pdu_sms/validity_period'
|
|
13
|
+
require 'pdu_sms/originating_address'
|
|
14
|
+
require 'pdu_sms/service_center_time_stamp'
|
|
15
|
+
require 'pdu_sms/packet_data_unit_error'
|
|
16
|
+
require 'pdu_sms/version'
|
|
17
|
+
|
|
18
|
+
module PduSms
|
|
19
|
+
|
|
20
|
+
include Helpers
|
|
21
|
+
##
|
|
22
|
+
# Type of number (TON):
|
|
23
|
+
ID_UNKNOWN = 0b000 # Unknown
|
|
24
|
+
ID_INTERNATIONAL = 0b001 # International number
|
|
25
|
+
ID_NATIONAL = 0b010 # National number
|
|
26
|
+
ID_NETWORK = 0b011 # Network specific number
|
|
27
|
+
ID_SUBSCRIBER = 0b100 # Subscriber number
|
|
28
|
+
ID_ALPHANUMERIC = 0b101 # Alphanumeric, (coded according to 3GPP TS 23.038 [9] GSM 7 bit default alphabet)
|
|
29
|
+
ID_ABBREVIATED = 0b110 # Abbreviated number
|
|
30
|
+
ID_RESERVED = 0b111 # Reserved for extension
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Numbering plan identification (NPI):
|
|
34
|
+
TP_UNKNOWN = 0b0000 # Unknown
|
|
35
|
+
TP_ISDN = 0b0001 # ISDN/telephone numbering plan (E.164/E.163)
|
|
36
|
+
TP_DATA = 0b0011 # Data numbering plan (X.121)
|
|
37
|
+
TP_TELEX = 0b100 # Telex numbering plan
|
|
38
|
+
TP_SERVICE_CENTER_SPECIFIC1 = 0b0101 # Service Centre Specific plan 1)
|
|
39
|
+
TP_SERVICE_CENTER_SPECIFIC2 = 0b0110 # Service Centre Specific plan 1)
|
|
40
|
+
TP_NATIONAL = 0b1000 # National numbering plan
|
|
41
|
+
TP_PRIVATE = 0b1001 # Private numbering plan
|
|
42
|
+
TP_ERMES = 0b1010 # ERMES numbering plan (ETSI DE/PS 3 01 3)
|
|
43
|
+
TP_RESERVED = 0b1111 # Reserved for extension
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Protocol Identifier
|
|
47
|
+
PROTOCOL_IDENTIFIER = 0x00 # Default store and forward short message
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# Data Coding Scheme
|
|
51
|
+
#6,7 bit
|
|
52
|
+
BIT0 = 0b00 # Default
|
|
53
|
+
COMPRESSED = 0b1 # Indicates the text is compressed using the GSM standard compression algorithm
|
|
54
|
+
UNCOMPRESSED = 0b0 # Indicates the text is uncompressed
|
|
55
|
+
MESSAGE_CLASS_OFF = 0b0 #
|
|
56
|
+
MESSAGE_CLASS_ON= 0b1 #
|
|
57
|
+
ALPHABET_7BIT = 0b00 # GSM 7 bit
|
|
58
|
+
ALPHABET_8BIT = 0b01 # 8 bit data
|
|
59
|
+
ALPHABET_16BIT = 0b10 # UCS2(16bit)
|
|
60
|
+
RESERVED = 0b11 # Reserved
|
|
61
|
+
CLASS_0_IMMEDIATE_DISPLAY = 0b00 # Flash messages are received by a mobile phone even though it has full memory. They are not stored in the phone, they just displayed on the phone display.
|
|
62
|
+
CLASS_1_ME_SPECIFIC = 0b01 # ME-specific
|
|
63
|
+
CLASS_2_SIM_SPECIFIC = 0b10 # SIM / USIM specific
|
|
64
|
+
CLASS_3_TE_SPECIFIC = 0b11 # TE-specific
|
|
65
|
+
|
|
66
|
+
##
|
|
67
|
+
# PDU TYPE
|
|
68
|
+
# @rp
|
|
69
|
+
REPLY_PATH_0 = 0b0 # Reply Path parameter is not set in this SMS-SUBMIT
|
|
70
|
+
REPLY_PATH_1 = 0b1 # Reply Path parameter is set in this SMS-SUBMIT
|
|
71
|
+
# @udhi
|
|
72
|
+
USER_DATA_HEADER_INCLUDED_0 = 0b0 # User Data field contains only the short message
|
|
73
|
+
USER_DATA_HEADER_INCLUDED_1 = 0b1 # The beginning of the UD field contains a Header in addition to the short message
|
|
74
|
+
# @srr
|
|
75
|
+
STATUS_REPORT_REQUEST_0 = 0b0 # A status report is not requested
|
|
76
|
+
STATUS_REPORT_REQUEST_1 = 0b1 # A status report is requested
|
|
77
|
+
# @vpf
|
|
78
|
+
VALIDITY_PERIOD_FORMAT_00 = 0b00 # Validity Period not present
|
|
79
|
+
VALIDITY_PERIOD_FORMAT_01 = 0b01 # Validity Period present- relative format
|
|
80
|
+
VALIDITY_PERIOD_FORMAT_10 = 0b10 # Validity Period present - enhanced format (reserved)
|
|
81
|
+
VALIDITY_PERIOD_FORMAT_11 = 0b11 # Validity Period present - absolute format
|
|
82
|
+
# @rd
|
|
83
|
+
REJECT_DUPLICATES_0 = 0b0 # Instruct the SC to accept SMS-SUBMIT for a SM still held in the SC which has the same MR and the same DA as a previously submitted SM from the same OA
|
|
84
|
+
REJECT_DUPLICATES_1 = 0b1 # Instruct the SC to reject an SMS-SUBMIT for an SM still held in the SC which has the same MR and the same DA as the previously submitted SM from the same OA. In this case an appropriate FCS value will be returned in the SMS-SUBMIT-REPORT
|
|
85
|
+
# @mti
|
|
86
|
+
MESSAGE_TYPE_INDICATOR_00 = 0b00 # SMS-DELIVER (in the direction SC to MS) SMS-DELIVER REPORT (in the direction MS to SC)
|
|
87
|
+
MESSAGE_TYPE_INDICATOR_01 = 0b01 # SMS-STATUS-REPORT (in the direction SC to MS) SMS-COMMAND (in the direction MS to SC)
|
|
88
|
+
MESSAGE_TYPE_INDICATOR_10 = 0b10 # SMS-SUBMIT (in the direction MS to SC) SMS-SUBMIT-REPORT (in the direction SC to MS)
|
|
89
|
+
MESSAGE_TYPE_INDICATOR_11 = 0b11 # Reserved
|
|
90
|
+
|
|
91
|
+
MORE_MESSAGES_TO_SEND_0 = 0b0 # More Message are waiting for the MS in the SMSC
|
|
92
|
+
MORE_MESSAGES_TO_SEND_1 = 0b1 # No more Message are waiting for the MS in the SMSC
|
|
93
|
+
|
|
94
|
+
STATUS_REPORT_INDICATION_0 = 0b0 # A status report will not be returned to the SME
|
|
95
|
+
STATUS_REPORT_INDICATION_1 = 0b1 # A status report will be returned to the SME
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
module PduSms
|
|
2
|
+
|
|
3
|
+
class DataCodingScheme
|
|
4
|
+
|
|
5
|
+
def initialize(type, compressed: UNCOMPRESSED, message_class: false, alphabet: ALPHABET_16BIT)
|
|
6
|
+
raise ArgumentError, 'The "compresses" is incorrect' unless compressed and (UNCOMPRESSED..COMPRESSED).include?(compressed)
|
|
7
|
+
raise ArgumentError, 'The "alphabet" is incorrect' unless alphabet and (ALPHABET_7BIT..RESERVED).include?(alphabet)
|
|
8
|
+
@compressed = compressed
|
|
9
|
+
@alphabet = alphabet
|
|
10
|
+
if message_class
|
|
11
|
+
if (CLASS_0_IMMEDIATE_DISPLAY..CLASS_3_TE_SPECIFIC).include?(message_class)
|
|
12
|
+
@message_class_trigger = MESSAGE_CLASS_ON
|
|
13
|
+
@message_class = message_class
|
|
14
|
+
else
|
|
15
|
+
raise ArgumentError, 'The "message_class" is incorrect'
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
@message_class_trigger = MESSAGE_CLASS_OFF
|
|
19
|
+
@message_class = 0b00
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def DataCodingScheme.encode_ms(compressed: UNCOMPRESSED, message_class: false, alphabet: ALPHABET_16BIT)
|
|
24
|
+
new(:encode_ms, compressed:compressed, message_class:message_class, alphabet:alphabet).freeze
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def DataCodingScheme.decode_ms(pdu_str)
|
|
28
|
+
pdu = '%08b' % DataCodingScheme.cut_off_pdu(pdu_str, :current, :ms).to_i(16)
|
|
29
|
+
message_class = (pdu[1].to_i == MESSAGE_CLASS_ON) ? pdu[6..7].to_i(2) : false
|
|
30
|
+
new(:decode_ms, compressed:pdu[2].to_i(2), message_class:message_class, alphabet:pdu[4..5].to_i(2)).freeze
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def DataCodingScheme.encode_sc(compressed: UNCOMPRESSED, message_class: false, alphabet: ALPHABET_16BIT)
|
|
34
|
+
new(:encode_sc, compressed:compressed, message_class:message_class, alphabet:alphabet).freeze
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def DataCodingScheme.decode_sc(pdu_str)
|
|
38
|
+
pdu = '%08b' % DataCodingScheme.cut_off_pdu(pdu_str, :current, :sc).to_i(16)
|
|
39
|
+
message_class = (pdu[1].to_i == MESSAGE_CLASS_ON) ? pdu[6..7].to_i(2) : false
|
|
40
|
+
new(:decode_sc, compressed:pdu[2].to_i(2), message_class:message_class, alphabet:pdu[4..5].to_i(2)).freeze
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def DataCodingScheme.cut_off_pdu(pdu, part=:all, type=:ms) # tail current
|
|
44
|
+
part_pdu = ProtocolIdentifier.cut_off_pdu(pdu, :tail, type)
|
|
45
|
+
raise ArgumentError, 'The "pdu" is incorrect' if part_pdu.length < 2
|
|
46
|
+
current = part_pdu[0..1]
|
|
47
|
+
tail = part_pdu[2..-1]
|
|
48
|
+
case part
|
|
49
|
+
when :current then current
|
|
50
|
+
when :tail then tail
|
|
51
|
+
else [current,tail]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def compressed?
|
|
56
|
+
@compressed == COMPRESSED
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def alphabet_7bit?
|
|
60
|
+
@alphabet == ALPHABET_7BIT
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def alphabet_8bit?
|
|
64
|
+
@alphabet == ALPHABET_8BIT
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def alphabet_16bit?
|
|
68
|
+
@alphabet == ALPHABET_16BIT
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def alphabet_reserved?
|
|
72
|
+
@alphabet == RESERVED
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def message_class?
|
|
76
|
+
@message_class_trigger == MESSAGE_CLASS_ON
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def message_class_immediate_display?
|
|
80
|
+
@message_class == CLASS_0_IMMEDIATE_DISPLAY
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def message_class_me?
|
|
84
|
+
@message_class == CLASS_1_ME_SPECIFIC
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def message_class_sim?
|
|
88
|
+
@message_class == CLASS_2_SIM_SPECIFIC
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def message_class_te?
|
|
92
|
+
@message_class == CLASS_3_TE_SPECIFIC
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def get_compressed
|
|
96
|
+
'%b' % @compressed
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def get_alphabet
|
|
100
|
+
'%02b' % @alphabet
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def get_message_class_trigger
|
|
104
|
+
'%b' % @message_class_trigger
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def get_message_class
|
|
108
|
+
'%02b' % @message_class
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def get_bit0
|
|
112
|
+
'%02b' % BIT0
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def get_hex
|
|
116
|
+
'%02x' % (get_bit0 << get_compressed << get_message_class_trigger << get_alphabet << get_message_class).to_i(2)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module PduSms
|
|
2
|
+
class DestinationAddress < Phone
|
|
3
|
+
|
|
4
|
+
def initialize(type=false, data=false, number_play_identifier=false, type_number=false)
|
|
5
|
+
if type == :decode_ms
|
|
6
|
+
_set_pdu_hex data
|
|
7
|
+
elsif type == :encode_ms
|
|
8
|
+
_set_phone_number data, number_play_identifier, type_number
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def DestinationAddress.encode_ms(phone_number, number_play_identifier=false, type_number=false)
|
|
13
|
+
new(:encode_ms, phone_number, number_play_identifier, type_number).freeze
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def DestinationAddress.decode_ms(pdu)
|
|
17
|
+
new(:decode_ms, DestinationAddress.cut_off_pdu(pdu, :current, :ms)).freeze
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def DestinationAddress.cut_off_pdu(pdu, part=:all, type=:ms) # tail current
|
|
21
|
+
part_pdu = MessageReference.cut_off_pdu(pdu, :tail)
|
|
22
|
+
raise ArgumentError, 'The "pdu" is incorrect' if part_pdu.length < 4
|
|
23
|
+
length = part_pdu[0..1].to_i(16)
|
|
24
|
+
if length % 2 == 0
|
|
25
|
+
current = part_pdu[0..length+3]
|
|
26
|
+
tail = part_pdu[length+4..-1]
|
|
27
|
+
else
|
|
28
|
+
current = part_pdu[0..length+4]
|
|
29
|
+
tail = part_pdu[length+5..-1]
|
|
30
|
+
end
|
|
31
|
+
case part
|
|
32
|
+
when :current then current
|
|
33
|
+
when :tail then tail
|
|
34
|
+
else [current,tail]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def get_hex
|
|
39
|
+
'%s%s' % [_address_length, _get_hex_type_and_phone]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
def _set_pdu_hex(str_pdu)
|
|
44
|
+
_set_hex_type_and_phone(str_pdu[2..-1])
|
|
45
|
+
self
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def _address_length
|
|
49
|
+
if @phone_number[0] == ?+
|
|
50
|
+
'%02x' % (@phone_number.length - 1)
|
|
51
|
+
else
|
|
52
|
+
'%02x' % @phone_number.length
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module PduSms
|
|
2
|
+
module Helpers
|
|
3
|
+
|
|
4
|
+
def encode_bcd(str)
|
|
5
|
+
if String == str.class and str.length % 2 == 0
|
|
6
|
+
str.split('').enum_for(:each_slice, 2).to_a.collect{|array| array[0], array[1] = array[1], array[0]}.join
|
|
7
|
+
else
|
|
8
|
+
raise ArgumentError, 'The number of characters must be even'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def decode_bcd(str)
|
|
13
|
+
encode_bcd(str)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def decode_ucs2(message)
|
|
17
|
+
message.split('').enum_for(:each_slice,4).to_a.collect(&:join).collect {|o| o.to_i(16).chr(Encoding::UTF_8)}.join
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def encode_ucs2(message)
|
|
21
|
+
message.chars.to_a.collect {|char| "%04X" % char.ord}.join
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def is_7bit?(message)
|
|
25
|
+
/^[A-Za-z0-9\@£\$¥èéùìòÇØøÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ\!\"#¤\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?¡¿ÄÖÑܧäöñüà\^\{\}\\\[~\]\|€]*$/ === message
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def encode_7bit(string)
|
|
29
|
+
string_encode = []
|
|
30
|
+
string.chars.each_slice(8).each do |chars|
|
|
31
|
+
chars.each_with_index do |char, i|
|
|
32
|
+
bit_char = '%07b' % char.ord
|
|
33
|
+
if i == 0
|
|
34
|
+
string_encode << bit_char
|
|
35
|
+
else
|
|
36
|
+
string_encode[-1] = '%s%s' % [bit_char[-i..-1], string_encode[-1]]
|
|
37
|
+
string_encode << bit_char[0..(-1-i)] if bit_char[0..(-1-i)] != ''
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
string_encode.collect {|x| '%02x' % x.to_i(2)}.join.upcase
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def decode_7bit(string)
|
|
45
|
+
text = ''
|
|
46
|
+
string.split('').each_slice(2).collect {|s| '%08b' % s.join.to_i(16)}.each_slice(7) do |bytes|
|
|
47
|
+
ending = ''
|
|
48
|
+
bytes.each_with_index do |byte, i|
|
|
49
|
+
text << ('0%s%s' % [byte[i+1..-1], ending]).to_i(2).chr
|
|
50
|
+
ending = byte[0..i]
|
|
51
|
+
text << ('0%s' % ending).to_i(2).chr if i == 6 and ending.to_i(2) != 0
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
text
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def encode_8bit(string)
|
|
58
|
+
string.chars.to_a.collect {|char| '%02x' % char.ord }.join
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def decode_8bit(string)
|
|
62
|
+
string.split('').enum_for(:each_slice, 2).to_a.collect(&:join).collect {|char| char.to_i(16).chr}.join
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|