empp 0.0.3
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/LICENSE.txt +20 -0
- data/README +0 -0
- data/README.rdoc +19 -0
- data/lib/empp.rb +2 -0
- data/lib/empp/constants.rb +28 -0
- data/lib/empp/delivery_state.rb +11 -0
- data/lib/empp/empp.rb +375 -0
- data/lib/empp/empp_base.rb +37 -0
- data/lib/empp/empp_connection.rb +90 -0
- data/lib/empp/empp_logger.rb +45 -0
- data/lib/empp/empp_msg_listener.rb +9 -0
- data/lib/empp/empp_parser.rb +176 -0
- data/lib/empp/empp_result_listener.rb +16 -0
- data/lib/empp/msg_active_test.rb +28 -0
- data/lib/empp/msg_active_test_resp.rb +14 -0
- data/lib/empp/msg_connect.rb +52 -0
- data/lib/empp/msg_connect_resp.rb +22 -0
- data/lib/empp/msg_delivery.rb +21 -0
- data/lib/empp/msg_delivery_resp.rb +35 -0
- data/lib/empp/msg_submit.rb +105 -0
- data/lib/empp/msg_submit_resp.rb +23 -0
- data/lib/empp/tcp_connection.rb +103 -0
- data/lib/empp/utils/bytebuffer.rb +39 -0
- data/lib/empp/utils/hashtable.rb +36 -0
- data/lib/empp/utils/utils.rb +120 -0
- data/test/helper.rb +3 -0
- data/test/test_empp.rb +161 -0
- data/test/test_msg_submit.rb +16 -0
- data/test/test_tcp_connection.rb +29 -0
- data/test/test_utils.rb +49 -0
- metadata +157 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'empp/empp_base'
|
2
|
+
require 'empp/constants'
|
3
|
+
|
4
|
+
module Empp
|
5
|
+
|
6
|
+
class MsgConnectResp < EmppBase
|
7
|
+
|
8
|
+
attr_accessor :status
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@command_id = Constants::EMPP_CONNECT_RESP
|
12
|
+
@status = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
str = super
|
17
|
+
str + ", status = #{@status}"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'empp/empp_base'
|
2
|
+
require 'empp/constants'
|
3
|
+
|
4
|
+
module Empp
|
5
|
+
|
6
|
+
class MsgDelivery < EmppBase
|
7
|
+
|
8
|
+
attr_accessor :msg_id, :dest_id, :service_id, :msg_format, :src_terminal_id, :registered_delivery, :msg_length, :msg_content
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@command_id = Constants::EMPP_DELIVER
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
str = super
|
16
|
+
str + "msg_id=#{@msg_id}, dest_id=#{@dest_id}, service_id=#{@service_id}, msg_format=#{@msg_format}, src_terminal_id=#{@src_terminal_id}, msg_length=#{@msg_length}, msg_content=#{@msg_content}"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'empp/empp_base'
|
2
|
+
require 'empp/utils/bytebuffer'
|
3
|
+
require 'empp/utils/utils'
|
4
|
+
require 'empp/constants'
|
5
|
+
|
6
|
+
module Empp
|
7
|
+
|
8
|
+
class MsgDeliveryResp < EmppBase
|
9
|
+
|
10
|
+
attr_accessor :msg_id
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@command_id = Constants::EMPP_DELIVER_RESP
|
14
|
+
@result = 0
|
15
|
+
@total_length = 12 + 10 + 4
|
16
|
+
setSequenceId
|
17
|
+
end
|
18
|
+
|
19
|
+
def package
|
20
|
+
buf = Utils::ByteBuffer.new
|
21
|
+
# add header
|
22
|
+
buf.append_uint_be(@total_length)
|
23
|
+
|
24
|
+
buf.append_uint_be(@command_id)
|
25
|
+
buf.append_uint_be(@sequence_id)
|
26
|
+
buf.append_string(@msg_id)
|
27
|
+
buf.append_string("\0\0\0\0")
|
28
|
+
|
29
|
+
buf.data
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'empp/empp_base'
|
2
|
+
require 'empp/constants'
|
3
|
+
require 'empp/empp_logger'
|
4
|
+
require 'empp/utils/bytebuffer'
|
5
|
+
require 'empp/utils/utils'
|
6
|
+
|
7
|
+
|
8
|
+
module Empp
|
9
|
+
|
10
|
+
class MsgSubmit < EmppBase
|
11
|
+
|
12
|
+
attr_accessor :terminal_id, :pk_total, :pk_number, :msg_id, :sequence_ids
|
13
|
+
|
14
|
+
def initialize(terminal_id, message, account_id, service_id)
|
15
|
+
@command_id = Constants::EMPP_SUBMIT
|
16
|
+
@terminal_id = terminal_id
|
17
|
+
@account_id = account_id
|
18
|
+
@service_id = service_id
|
19
|
+
@message = Utils::Utils.convert_utf8_to_gbk(message)
|
20
|
+
@splitted_messages = Utils::Utils.get_splitted_msgs(@message)
|
21
|
+
@sequence_ids = []
|
22
|
+
# assign sequence_id for each slice
|
23
|
+
@splitted_messages.each do |msg|
|
24
|
+
setSequenceId
|
25
|
+
@sequence_ids << @sequence_id
|
26
|
+
end
|
27
|
+
|
28
|
+
@msg_id = Time.now.to_i.to_s[0...10]
|
29
|
+
|
30
|
+
@pk_total = @splitted_messages.length
|
31
|
+
@pk_number = 1
|
32
|
+
|
33
|
+
@logger = EmppLogger.instance
|
34
|
+
end
|
35
|
+
|
36
|
+
def package
|
37
|
+
@logger.debug("Enter MsgSubmit::package")
|
38
|
+
|
39
|
+
tmp_buf = ''
|
40
|
+
index = 0
|
41
|
+
|
42
|
+
@splitted_messages.each do |msg|
|
43
|
+
@sequence_id = @sequence_ids[index]
|
44
|
+
index += 1
|
45
|
+
tmp_buf << package_msg(msg)
|
46
|
+
end
|
47
|
+
|
48
|
+
@logger.debug("Leave MsgSubmit::package")
|
49
|
+
|
50
|
+
tmp_buf
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def package_msg(a_msg)
|
56
|
+
@logger.debug("Enter MsgSubmit::package_msg")
|
57
|
+
buf = Utils::ByteBuffer.new
|
58
|
+
@total_length = 12 + 10 + 1*4 + 17 + 17 + 4 + 32*1 + 1 + a_msg.length + 21*2 + 10 + 20 + 1*2 + 32 + 1*3 + 2 + 6 + 1
|
59
|
+
|
60
|
+
|
61
|
+
# add header
|
62
|
+
buf.append_uint_be(@total_length)
|
63
|
+
|
64
|
+
buf.append_uint_be(@command_id)
|
65
|
+
buf.append_uint_be(@sequence_id)
|
66
|
+
|
67
|
+
buf.append_string(@msg_id)
|
68
|
+
|
69
|
+
tmp_str = ''
|
70
|
+
tmp_str << @pk_total
|
71
|
+
buf.append_string(tmp_str)
|
72
|
+
|
73
|
+
tmp_str = ''
|
74
|
+
tmp_str << @pk_number
|
75
|
+
@pk_number += 1
|
76
|
+
buf.append_string(tmp_str)
|
77
|
+
|
78
|
+
buf.append_string("\1")
|
79
|
+
buf.append_string("\017") # 15
|
80
|
+
buf.append_string("\0" * 17)
|
81
|
+
buf.append_string("\0" * 17)
|
82
|
+
buf.append_uint_be(1)
|
83
|
+
buf.append_string(@terminal_id.ljust(32, "\0"))
|
84
|
+
buf.append_string([a_msg.length].pack("C"))
|
85
|
+
buf.append_string(a_msg)
|
86
|
+
buf.append_string(" " * 21)
|
87
|
+
buf.append_string(@account_id.ljust(21, "\0"))
|
88
|
+
buf.append_string(@service_id.ljust(10, "\0"))
|
89
|
+
buf.append_string("\0" * 20)
|
90
|
+
buf.append_string("\0")
|
91
|
+
buf.append_string("\0")
|
92
|
+
buf.append_string("\0" * 32)
|
93
|
+
buf.append_string("\0")
|
94
|
+
buf.append_string("\0")
|
95
|
+
buf.append_string("\0")
|
96
|
+
buf.append_string("\0" * 2)
|
97
|
+
buf.append_string("\0" * 6)
|
98
|
+
buf.append_string("\0")
|
99
|
+
|
100
|
+
@logger.debug("Leave MsgSubmit::package_msg")
|
101
|
+
buf.data
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'empp/empp_base'
|
2
|
+
require 'empp/constants'
|
3
|
+
|
4
|
+
module Empp
|
5
|
+
|
6
|
+
class MsgSubmitResp < EmppBase
|
7
|
+
|
8
|
+
attr_accessor :status, :msg_id
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@command_id = Constants::EMPP_SUBMIT_RESP
|
12
|
+
@msg_id = nil
|
13
|
+
@status = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
str = super
|
18
|
+
str + ", status = #{@status}, msg_id=#{@msg_id}"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'empp/empp_logger'
|
3
|
+
|
4
|
+
module Empp
|
5
|
+
|
6
|
+
class TcpConnection
|
7
|
+
|
8
|
+
def initialize(host, port)
|
9
|
+
@socket = nil
|
10
|
+
@host = host
|
11
|
+
@port = port
|
12
|
+
@max_to_read = 4096
|
13
|
+
@logger = EmppLogger.instance
|
14
|
+
@alive = false
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.getConnection(host, port)
|
18
|
+
return self.new(host, port)
|
19
|
+
end
|
20
|
+
|
21
|
+
def alive?
|
22
|
+
@alive
|
23
|
+
end
|
24
|
+
|
25
|
+
def send(data)
|
26
|
+
@logger.debug("Enter TcpConnection::send")
|
27
|
+
|
28
|
+
@logger.debug("TcpConnection: send bytes:#{data.unpack("H*")}")
|
29
|
+
if @socket
|
30
|
+
begin
|
31
|
+
@socket.write(data)
|
32
|
+
rescue
|
33
|
+
@logger.fatal("Get exception to write data")
|
34
|
+
@alive = false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
@logger.debug("Leave TcpConnection::send")
|
39
|
+
end
|
40
|
+
|
41
|
+
def connect
|
42
|
+
@logger.debug("Enter TcpConnection::connect")
|
43
|
+
|
44
|
+
begin
|
45
|
+
@socket = TCPSocket.new(@host, @port)
|
46
|
+
@alive = true
|
47
|
+
rescue
|
48
|
+
@alive = false
|
49
|
+
@socket = nil
|
50
|
+
@logger.fatal("Open socket error for host=#{@host}, port=#{@port}")
|
51
|
+
end
|
52
|
+
|
53
|
+
@logger.debug("Leave TcpConnection::connect")
|
54
|
+
end
|
55
|
+
|
56
|
+
def close
|
57
|
+
@logger.debug("Enter TcpConnection::close")
|
58
|
+
|
59
|
+
begin
|
60
|
+
@alive = false
|
61
|
+
if @socket
|
62
|
+
@socket.close()
|
63
|
+
end
|
64
|
+
rescue
|
65
|
+
@logger.warn("Unable to close socket.")
|
66
|
+
end
|
67
|
+
|
68
|
+
@logger.debug("Leave TcpConnection::close")
|
69
|
+
end
|
70
|
+
|
71
|
+
def receive(count = 0)
|
72
|
+
@logger.debug("Enter TcpConnection::receive")
|
73
|
+
|
74
|
+
count ||= @max_to_read
|
75
|
+
|
76
|
+
if count < 0 || count > @max_to_read
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
bytes = nil
|
81
|
+
begin
|
82
|
+
|
83
|
+
while !bytes || bytes.length == 0
|
84
|
+
if @socket
|
85
|
+
bytes = @socket.recvfrom(count)[0]
|
86
|
+
else
|
87
|
+
raise
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
rescue
|
92
|
+
@logger.fatal("TcpConnection::receive: get exception from socket recvFrom")
|
93
|
+
@alive = false
|
94
|
+
return
|
95
|
+
end
|
96
|
+
@logger.info("TcpConnectin receive bytes=" + bytes.unpack("H*").to_s )
|
97
|
+
@logger.debug("Leave TcpConnection::receive")
|
98
|
+
return bytes
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'bindata'
|
2
|
+
require 'empp/utils/utils'
|
3
|
+
|
4
|
+
module Empp
|
5
|
+
|
6
|
+
module Utils
|
7
|
+
|
8
|
+
class ByteBuffer
|
9
|
+
|
10
|
+
def initialize(data = nil)
|
11
|
+
@buf = data || ''
|
12
|
+
@offset = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def append_uint_be(intValue)
|
16
|
+
@buf << Utils.getUintBe(intValue)
|
17
|
+
end
|
18
|
+
|
19
|
+
def append_uint_le(intValue)
|
20
|
+
@buf << Utils.getUintLe(intValue)
|
21
|
+
end
|
22
|
+
|
23
|
+
def append_string(strValue)
|
24
|
+
@buf << strValue
|
25
|
+
end
|
26
|
+
|
27
|
+
def data
|
28
|
+
@buf
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
@buf.unpack("H*")
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Empp
|
4
|
+
|
5
|
+
module Utils
|
6
|
+
|
7
|
+
class Hashtable < Hash
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
@mutex = Mutex.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def put(key, value)
|
15
|
+
@mutex.synchronize{
|
16
|
+
self[key] = value
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def get(key)
|
21
|
+
@mutex.synchronize{
|
22
|
+
self[key]
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete(key)
|
27
|
+
@mutex.synchronize{
|
28
|
+
super(key)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
|
2
|
+
require 'bindata'
|
3
|
+
require 'iconv'
|
4
|
+
|
5
|
+
module Empp
|
6
|
+
|
7
|
+
module Utils
|
8
|
+
|
9
|
+
class Utils
|
10
|
+
|
11
|
+
# MMDDHHMMSS
|
12
|
+
def self.getTimestampInt(now)
|
13
|
+
u8 = BinData::Uint8.new
|
14
|
+
intVal = now.month * 10**8 + now.day * 10**6 + now.hour * 10**4 + now.min * 10**2 + now.sec
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.getTimestampStr(now)
|
18
|
+
now.month.to_s.rjust(2, "0") + now.day.to_s.rjust(2, "0") + now.hour.to_s.rjust(2, "0") + now.min.to_s.rjust(2, "0") + now.sec.to_s.rjust(2, "0")
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.getUintLe(intValue)
|
22
|
+
ibe = BinData::Uint32le.new
|
23
|
+
ibe.assign( intValue )
|
24
|
+
ibe.to_binary_s
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.getUintBe(intValue)
|
28
|
+
ibe = BinData::Uint32be.new
|
29
|
+
ibe.assign( intValue )
|
30
|
+
ibe.to_binary_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.getVersion
|
34
|
+
version = 0b00010000
|
35
|
+
u8 = BinData::Uint8be.new
|
36
|
+
u8.assign(version)
|
37
|
+
u8.to_binary_s
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def self.fill_zero(binaryStr)
|
43
|
+
binaryStr.rjust(2, "\0")
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.convert_utf8_to_gbk(strVal)
|
47
|
+
conv = Iconv.new("gbk", "utf-8")
|
48
|
+
conv.iconv(strVal)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.convert_gbk_to_utf8(strVal)
|
52
|
+
conv = Iconv.new("utf-8", "gbk")
|
53
|
+
conv.iconv(strVal)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.convert_ucs2_to_utf8(strVal)
|
57
|
+
conv = Iconv.new("utf-8", "utf-16")
|
58
|
+
conv.iconv(strVal)
|
59
|
+
end
|
60
|
+
|
61
|
+
###########################################################
|
62
|
+
## strip the possible prefix like "86" "+86" in ##
|
63
|
+
## terminal_id ##
|
64
|
+
###########################################################
|
65
|
+
def self.deal_with_terminal_id(terminal_id)
|
66
|
+
|
67
|
+
start_index = 0
|
68
|
+
if terminal_id.start_with?"86"
|
69
|
+
start_index = 2
|
70
|
+
elsif terminal_id.start_with?"+86"
|
71
|
+
start_index = 3
|
72
|
+
end
|
73
|
+
terminal_id[start_index .. -1]
|
74
|
+
end
|
75
|
+
|
76
|
+
############################################################
|
77
|
+
## split msg_content to slices which has characters<70 ##
|
78
|
+
## to fit empp's requirement, msg_content is coded as gbk ##
|
79
|
+
############################################################
|
80
|
+
def self.get_splitted_msgs(msg_content)
|
81
|
+
fix_len = 68
|
82
|
+
msgs = []
|
83
|
+
count, index = 0, 0;
|
84
|
+
tmp_str = ''
|
85
|
+
step = 1
|
86
|
+
|
87
|
+
while true
|
88
|
+
|
89
|
+
if count > fix_len || index >= msg_content.length
|
90
|
+
msgs << tmp_str
|
91
|
+
tmp_str = ''
|
92
|
+
count = 0
|
93
|
+
end
|
94
|
+
|
95
|
+
break if index >= msg_content.length
|
96
|
+
bt = msg_content[index]
|
97
|
+
|
98
|
+
if bt.to_i < 128 && bt.to_i > 0
|
99
|
+
tmp_str << msg_content[index]
|
100
|
+
step = 1
|
101
|
+
else
|
102
|
+
tmp_str << msg_content[index]
|
103
|
+
tmp_str << msg_content[index + 1]
|
104
|
+
step = 2
|
105
|
+
end
|
106
|
+
|
107
|
+
index += step
|
108
|
+
count += 1
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
msgs
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|