ruby_ucp 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.
- data/CHANGELOG +42 -0
- data/LICENSE +505 -0
- data/README +10 -0
- data/Rakefile +118 -0
- data/Rakefile.orig +45 -0
- data/VERSION +1 -0
- data/lib/ruby_ucp.rb +42 -0
- data/lib/samples/main.rb +182 -0
- data/lib/ucp/base.rb +24 -0
- data/lib/ucp/pdu/base.rb +22 -0
- data/lib/ucp/pdu/ucp01.rb +37 -0
- data/lib/ucp/pdu/ucp01_operation.rb +61 -0
- data/lib/ucp/pdu/ucp01_result.rb +60 -0
- data/lib/ucp/pdu/ucp30.rb +28 -0
- data/lib/ucp/pdu/ucp30_operation.rb +59 -0
- data/lib/ucp/pdu/ucp30_result.rb +63 -0
- data/lib/ucp/pdu/ucp31.rb +29 -0
- data/lib/ucp/pdu/ucp31_operation.rb +50 -0
- data/lib/ucp/pdu/ucp31_result.rb +61 -0
- data/lib/ucp/pdu/ucp51_operation.rb +167 -0
- data/lib/ucp/pdu/ucp51_result.rb +64 -0
- data/lib/ucp/pdu/ucp52_operation.rb +31 -0
- data/lib/ucp/pdu/ucp52_result.rb +31 -0
- data/lib/ucp/pdu/ucp53_operation.rb +31 -0
- data/lib/ucp/pdu/ucp53_result.rb +31 -0
- data/lib/ucp/pdu/ucp54_operation.rb +31 -0
- data/lib/ucp/pdu/ucp54_result.rb +31 -0
- data/lib/ucp/pdu/ucp55_operation.rb +31 -0
- data/lib/ucp/pdu/ucp55_result.rb +31 -0
- data/lib/ucp/pdu/ucp56_operation.rb +31 -0
- data/lib/ucp/pdu/ucp56_result.rb +31 -0
- data/lib/ucp/pdu/ucp57_operation.rb +31 -0
- data/lib/ucp/pdu/ucp57_result.rb +31 -0
- data/lib/ucp/pdu/ucp58_operation.rb +31 -0
- data/lib/ucp/pdu/ucp58_result.rb +31 -0
- data/lib/ucp/pdu/ucp5x.rb +40 -0
- data/lib/ucp/pdu/ucp60.rb +30 -0
- data/lib/ucp/pdu/ucp60_operation.rb +58 -0
- data/lib/ucp/pdu/ucp60_result.rb +60 -0
- data/lib/ucp/pdu/ucp61.rb +31 -0
- data/lib/ucp/pdu/ucp61_operation.rb +49 -0
- data/lib/ucp/pdu/ucp61_result.rb +60 -0
- data/lib/ucp/pdu/ucp_operation.rb +27 -0
- data/lib/ucp/pdu/ucp_result.rb +26 -0
- data/lib/ucp/pdu/ucpmessage.rb +125 -0
- data/lib/ucp/util/base.rb +22 -0
- data/lib/ucp/util/gsm_packed_msg.rb +50 -0
- data/lib/ucp/util/packed_msg.rb +34 -0
- data/lib/ucp/util/sms_request.rb +48 -0
- data/lib/ucp/util/ucp.rb +885 -0
- data/lib/ucp/util/ucp_client.rb +207 -0
- data/lib/ucp/util/ucp_server.rb +122 -0
- data/lib/ucp/util/ucs2_packed_msg.rb +29 -0
- metadata +120 -0
@@ -0,0 +1,207 @@
|
|
1
|
+
=begin
|
2
|
+
Ruby library implementation of EMI/UCP protocol v4.6 for SMS
|
3
|
+
Copyright (C) 2011, Sergio Freire <sergio.freire@gmail.com>
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU Lesser General Public
|
7
|
+
License as published by the Free Software Foundation; either
|
8
|
+
version 2.1 of the License, or (at your option) any later version.
|
9
|
+
|
10
|
+
This library is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public
|
16
|
+
License along with this library; if not, write to the Free Software
|
17
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
+
=end
|
19
|
+
|
20
|
+
|
21
|
+
require "socket"
|
22
|
+
|
23
|
+
include Ucp::Pdu
|
24
|
+
include Ucp::Util
|
25
|
+
|
26
|
+
class Ucp::Util::UcpClient
|
27
|
+
|
28
|
+
@trn=0
|
29
|
+
@mr=0
|
30
|
+
|
31
|
+
def initialize(host,port, authcreds=nil)
|
32
|
+
@host=host
|
33
|
+
@port=port
|
34
|
+
@connected=false
|
35
|
+
@authcreds=authcreds
|
36
|
+
@trn=0
|
37
|
+
@mr=0
|
38
|
+
connect()
|
39
|
+
end
|
40
|
+
|
41
|
+
def connect
|
42
|
+
#puts "connect()"
|
43
|
+
|
44
|
+
begin
|
45
|
+
@socket = TCPSocket.new(@host, @port)
|
46
|
+
@connected=true
|
47
|
+
@trn=0
|
48
|
+
rescue
|
49
|
+
@connected=false
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
if !@authcreds.nil?
|
55
|
+
auth_ucp=Ucp60Operation.new
|
56
|
+
auth_ucp.basic_auth(@authcreds[:login],@authcreds[:password])
|
57
|
+
auth_ucp.trn="00"
|
58
|
+
answer=send_sync(auth_ucp)
|
59
|
+
#puts "Crecv: #{answer.to_s}\n"
|
60
|
+
|
61
|
+
if !answer.nil? && answer.is_ack?
|
62
|
+
inc_trn()
|
63
|
+
return true
|
64
|
+
else
|
65
|
+
close()
|
66
|
+
return false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
def close
|
73
|
+
begin
|
74
|
+
@socket.close
|
75
|
+
rescue
|
76
|
+
end
|
77
|
+
@connected=false
|
78
|
+
end
|
79
|
+
|
80
|
+
def connected?
|
81
|
+
if !@socket.nil? && !@socket.closed? && @connected
|
82
|
+
@connected=true
|
83
|
+
else
|
84
|
+
@connected=false
|
85
|
+
end
|
86
|
+
return @connected
|
87
|
+
end
|
88
|
+
|
89
|
+
def send_sync(ucp)
|
90
|
+
#puts "XXXX0"
|
91
|
+
|
92
|
+
if !connected?
|
93
|
+
connect()
|
94
|
+
# se nao foi possivel ligar, retornar imediatamente com erro
|
95
|
+
if !connected?
|
96
|
+
return nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
#puts "XXXX1"
|
101
|
+
|
102
|
+
answer=nil
|
103
|
+
begin
|
104
|
+
@socket.print ucp.to_s
|
105
|
+
puts "Csent: #{ucp.to_s}\n"
|
106
|
+
answer = @socket.gets(3.chr)
|
107
|
+
#answer = @socket.gets("#")
|
108
|
+
puts "Crecv: #{answer.to_s}\n"
|
109
|
+
rescue
|
110
|
+
puts "error: #{$!}"
|
111
|
+
@connected=false
|
112
|
+
end
|
113
|
+
|
114
|
+
# verificar o trn da resposta face a submissao
|
115
|
+
replyucp=UCP.parse_str(answer)
|
116
|
+
return nil if replyucp.nil?
|
117
|
+
|
118
|
+
if !ucp.trn.eql?(replyucp.trn)
|
119
|
+
puts "unexpected trn #{replyucp.trn}. should be #{ucp.trn}"
|
120
|
+
return nil
|
121
|
+
else
|
122
|
+
return replyucp
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def send(ucp)
|
127
|
+
if !connected?
|
128
|
+
connect()
|
129
|
+
# se nao foi possivel ligar, retornar imediatamente com erro
|
130
|
+
if !connected?
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
begin
|
136
|
+
@socket.print ucp.to_s
|
137
|
+
rescue
|
138
|
+
puts "error: #{$!}"
|
139
|
+
# deu erro, vamos fechar o socket
|
140
|
+
close()
|
141
|
+
# error
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
|
145
|
+
# OK
|
146
|
+
return true
|
147
|
+
end
|
148
|
+
|
149
|
+
def read
|
150
|
+
answer=nil
|
151
|
+
begin
|
152
|
+
answer = @socket.gets(3.chr)
|
153
|
+
rescue
|
154
|
+
puts "error: #{$!}"
|
155
|
+
# deu erro, vamos fechar o socket
|
156
|
+
close()
|
157
|
+
end
|
158
|
+
|
159
|
+
return answer
|
160
|
+
end
|
161
|
+
|
162
|
+
def send_message(originator,recipient,message)
|
163
|
+
#ucp=Ucp51Operation.new(originator,recipient,message)
|
164
|
+
|
165
|
+
ucps=UCP.make_multi_ucps(originator,recipient,message,@mr)
|
166
|
+
inc_mr()
|
167
|
+
|
168
|
+
ucps.each { |ucp|
|
169
|
+
ucp.trn=UCP.int2hex(@trn)
|
170
|
+
ans=send_sync(ucp)
|
171
|
+
inc_trn()
|
172
|
+
# puts "e um ack: #{ans.nil?} ; #{ans.is_ack?}"
|
173
|
+
return false if ans.nil? || !ans.is_ack?
|
174
|
+
}
|
175
|
+
|
176
|
+
|
177
|
+
return true
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
def send_alert(recipient,pid)
|
182
|
+
ucp=Ucp31Operation.new
|
183
|
+
ucp.basic_alert(recipient,pid)
|
184
|
+
|
185
|
+
trn=UCP.int2hex(@trn)
|
186
|
+
ucp.trn=trn
|
187
|
+
ans=send_sync(ucp)
|
188
|
+
inc_trn()
|
189
|
+
# puts "e um ack: #{ans.nil?} ; #{ans.is_ack?}"
|
190
|
+
return false if ans.nil? || !ans.is_ack?
|
191
|
+
|
192
|
+
return true
|
193
|
+
end
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
def inc_trn
|
198
|
+
@trn+=1
|
199
|
+
@trn=0 if @trn>99
|
200
|
+
end
|
201
|
+
|
202
|
+
def inc_mr
|
203
|
+
@mr+=1
|
204
|
+
@mr=0 if @mr>255
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
=begin
|
2
|
+
Ruby library implementation of EMI/UCP protocol v4.6 for SMS
|
3
|
+
Copyright (C) 2011, Sergio Freire <sergio.freire@gmail.com>
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU Lesser General Public
|
7
|
+
License as published by the Free Software Foundation; either
|
8
|
+
version 2.1 of the License, or (at your option) any later version.
|
9
|
+
|
10
|
+
This library is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public
|
16
|
+
License along with this library; if not, write to the Free Software
|
17
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'socket'
|
21
|
+
|
22
|
+
class ClientQuitError < RuntimeError; end
|
23
|
+
|
24
|
+
#class UcpServer
|
25
|
+
|
26
|
+
include Ucp::Pdu
|
27
|
+
include Ucp::Util
|
28
|
+
|
29
|
+
class Ucp::Util::UcpServer
|
30
|
+
|
31
|
+
@server=nil
|
32
|
+
|
33
|
+
def initialize(handler,port,host=nil)
|
34
|
+
|
35
|
+
# serv = TCPServer.new(port)
|
36
|
+
# begin
|
37
|
+
# @sock = serv.accept_nonblock
|
38
|
+
# rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR
|
39
|
+
# IO.select([serv])
|
40
|
+
# retry
|
41
|
+
# end
|
42
|
+
# # sock is an accepted socket.
|
43
|
+
|
44
|
+
# end
|
45
|
+
|
46
|
+
|
47
|
+
@server = host ? TCPServer.open(host, port) : TCPServer.open(port)
|
48
|
+
@server.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
49
|
+
|
50
|
+
|
51
|
+
port = @server.addr[1]
|
52
|
+
addrs = @server.addr[2..-1].uniq
|
53
|
+
|
54
|
+
puts "*** listening on #{addrs.collect{|a|"#{a}:#{port}"}.join(' ')}"
|
55
|
+
|
56
|
+
Thread.start do
|
57
|
+
|
58
|
+
loop do
|
59
|
+
socket = @server.accept
|
60
|
+
|
61
|
+
Thread.start do # one thread per client
|
62
|
+
s = socket
|
63
|
+
|
64
|
+
port = s.peeraddr[1]
|
65
|
+
name = s.peeraddr[2]
|
66
|
+
addr = s.peeraddr[3]
|
67
|
+
|
68
|
+
#puts "*** recieving from #{name}:#{port}"
|
69
|
+
|
70
|
+
begin
|
71
|
+
while line = s.gets(3.chr) # read a line at a time
|
72
|
+
raise ClientQuitError if line =~ /^die\r?$/
|
73
|
+
|
74
|
+
#puts "#{addr} [#{Time.now}]: #{line}"
|
75
|
+
|
76
|
+
puts "Srecv: #{line}\n"
|
77
|
+
ucp=UCP.parse_str(line)
|
78
|
+
|
79
|
+
if ucp.operation.eql?("01") || ucp.operation.eql?("30") || ucp.operation.eql?("51") || ucp.operation.eql?("52")
|
80
|
+
text=UCP.decode_ucp_msg(ucp)
|
81
|
+
#puts "texto_recebido: #{text}\n"
|
82
|
+
account="unknown"
|
83
|
+
smsreq=SmsRequest.new(UCP.decode_ucp_oadc(ucp),ucp.get_field(:adc),text,account,addr,port)
|
84
|
+
smsreq.set_parts_info(ucp.message_ref, ucp.part_nr, ucp.total_parts)
|
85
|
+
handler.call(smsreq)
|
86
|
+
end
|
87
|
+
|
88
|
+
reply_ucp=UCP.make_ucp_result(ucp)
|
89
|
+
#puts "bbbbbbbbbbbbb1"
|
90
|
+
reply_ucp.ack("ok")
|
91
|
+
#puts "bbbbbbbbbbbbb2"
|
92
|
+
#puts "reply #{reply_ucp.to_s}"
|
93
|
+
s.print reply_ucp.to_s
|
94
|
+
puts "Ssent: #{reply_ucp.to_s}\n"
|
95
|
+
end
|
96
|
+
rescue ClientQuitError
|
97
|
+
puts "*** #{name}:#{port} disconnected"
|
98
|
+
ensure
|
99
|
+
s.close # close socket on error
|
100
|
+
end
|
101
|
+
|
102
|
+
puts "*** done with #{name}:#{port}"
|
103
|
+
# end Thread
|
104
|
+
end
|
105
|
+
|
106
|
+
# end loop
|
107
|
+
end
|
108
|
+
|
109
|
+
# end Thread accept
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# end initialize
|
114
|
+
end
|
115
|
+
|
116
|
+
def stop
|
117
|
+
@server.close
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
=begin
|
2
|
+
Ruby library implementation of EMI/UCP protocol v4.6 for SMS
|
3
|
+
Copyright (C) 2011, Sergio Freire <sergio.freire@gmail.com>
|
4
|
+
|
5
|
+
This library is free software; you can redistribute it and/or
|
6
|
+
modify it under the terms of the GNU Lesser General Public
|
7
|
+
License as published by the Free Software Foundation; either
|
8
|
+
version 2.1 of the License, or (at your option) any later version.
|
9
|
+
|
10
|
+
This library is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public
|
16
|
+
License along with this library; if not, write to the Free Software
|
17
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
+
=end
|
19
|
+
|
20
|
+
class Ucp::Util::Ucs2PackedMsg < Ucp::Util::PackedMsg
|
21
|
+
|
22
|
+
def initialize(encoded,unencoded,chars,required_octets)
|
23
|
+
@encoded=encoded
|
24
|
+
@unencoded=unencoded
|
25
|
+
@chars=chars
|
26
|
+
@required_octets=required_octets
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_ucp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Sergio Freire
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-16 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Ruby library implementation of EMI/UCP protocol v4.6 for SMS
|
23
|
+
email: sergio.freire@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- LICENSE
|
30
|
+
- README
|
31
|
+
files:
|
32
|
+
- CHANGELOG
|
33
|
+
- LICENSE
|
34
|
+
- README
|
35
|
+
- Rakefile
|
36
|
+
- Rakefile.orig
|
37
|
+
- VERSION
|
38
|
+
- lib/ruby_ucp.rb
|
39
|
+
- lib/samples/main.rb
|
40
|
+
- lib/ucp/base.rb
|
41
|
+
- lib/ucp/pdu/base.rb
|
42
|
+
- lib/ucp/pdu/ucp01.rb
|
43
|
+
- lib/ucp/pdu/ucp01_operation.rb
|
44
|
+
- lib/ucp/pdu/ucp01_result.rb
|
45
|
+
- lib/ucp/pdu/ucp30.rb
|
46
|
+
- lib/ucp/pdu/ucp30_operation.rb
|
47
|
+
- lib/ucp/pdu/ucp30_result.rb
|
48
|
+
- lib/ucp/pdu/ucp31.rb
|
49
|
+
- lib/ucp/pdu/ucp31_operation.rb
|
50
|
+
- lib/ucp/pdu/ucp31_result.rb
|
51
|
+
- lib/ucp/pdu/ucp51_operation.rb
|
52
|
+
- lib/ucp/pdu/ucp51_result.rb
|
53
|
+
- lib/ucp/pdu/ucp52_operation.rb
|
54
|
+
- lib/ucp/pdu/ucp52_result.rb
|
55
|
+
- lib/ucp/pdu/ucp53_operation.rb
|
56
|
+
- lib/ucp/pdu/ucp53_result.rb
|
57
|
+
- lib/ucp/pdu/ucp54_operation.rb
|
58
|
+
- lib/ucp/pdu/ucp54_result.rb
|
59
|
+
- lib/ucp/pdu/ucp55_operation.rb
|
60
|
+
- lib/ucp/pdu/ucp55_result.rb
|
61
|
+
- lib/ucp/pdu/ucp56_operation.rb
|
62
|
+
- lib/ucp/pdu/ucp56_result.rb
|
63
|
+
- lib/ucp/pdu/ucp57_operation.rb
|
64
|
+
- lib/ucp/pdu/ucp57_result.rb
|
65
|
+
- lib/ucp/pdu/ucp58_operation.rb
|
66
|
+
- lib/ucp/pdu/ucp58_result.rb
|
67
|
+
- lib/ucp/pdu/ucp5x.rb
|
68
|
+
- lib/ucp/pdu/ucp60.rb
|
69
|
+
- lib/ucp/pdu/ucp60_operation.rb
|
70
|
+
- lib/ucp/pdu/ucp60_result.rb
|
71
|
+
- lib/ucp/pdu/ucp61.rb
|
72
|
+
- lib/ucp/pdu/ucp61_operation.rb
|
73
|
+
- lib/ucp/pdu/ucp61_result.rb
|
74
|
+
- lib/ucp/pdu/ucp_operation.rb
|
75
|
+
- lib/ucp/pdu/ucp_result.rb
|
76
|
+
- lib/ucp/pdu/ucpmessage.rb
|
77
|
+
- lib/ucp/util/base.rb
|
78
|
+
- lib/ucp/util/gsm_packed_msg.rb
|
79
|
+
- lib/ucp/util/packed_msg.rb
|
80
|
+
- lib/ucp/util/sms_request.rb
|
81
|
+
- lib/ucp/util/ucp.rb
|
82
|
+
- lib/ucp/util/ucp_client.rb
|
83
|
+
- lib/ucp/util/ucp_server.rb
|
84
|
+
- lib/ucp/util/ucs2_packed_msg.rb
|
85
|
+
has_rdoc: true
|
86
|
+
homepage: https://github.com/bitcoder/ruby_ucp
|
87
|
+
licenses: []
|
88
|
+
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
hash: 3
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
version: "0"
|
112
|
+
requirements: []
|
113
|
+
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.3.7
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: EMI/UCP protocol library
|
119
|
+
test_files: []
|
120
|
+
|