tipcsocket 0.1
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 +7 -0
- data/LICENSE +20 -0
- data/README +77 -0
- data/Rakefile +56 -0
- data/demo/hello_world/client.rb +55 -0
- data/demo/hello_world/server.rb +29 -0
- data/demo/stream_demo/client.rb +121 -0
- data/demo/stream_demo/server.rb +69 -0
- data/lib/tipcsocket.rb +514 -0
- metadata +54 -0
data/CHANGELOG
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2007 Corey Burrows
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
= TIPCSocket
|
|
2
|
+
|
|
3
|
+
Ruby bindings for the TIPC[http://tipc.sourceforge.net] native socket API.
|
|
4
|
+
|
|
5
|
+
= Installing TIPCSocket
|
|
6
|
+
|
|
7
|
+
Get TIPCSocket from RubyForge.
|
|
8
|
+
|
|
9
|
+
$ gem install tipcsocket
|
|
10
|
+
|
|
11
|
+
= Example
|
|
12
|
+
|
|
13
|
+
Server:
|
|
14
|
+
|
|
15
|
+
require 'rubygems'
|
|
16
|
+
require 'tipcsocket'
|
|
17
|
+
|
|
18
|
+
include TIPCSocket::Constants
|
|
19
|
+
|
|
20
|
+
server_addr = TIPCNameSeq.new(18888, 17, 17, TIPC_ZONE_SCOPE)
|
|
21
|
+
|
|
22
|
+
s = TIPCSocket.new(:rdm)
|
|
23
|
+
s.bind(server_addr)
|
|
24
|
+
|
|
25
|
+
data, client = s.recvfrom(65535)
|
|
26
|
+
|
|
27
|
+
client = TIPCSocket.unpack_sockaddr(client)
|
|
28
|
+
|
|
29
|
+
p client
|
|
30
|
+
|
|
31
|
+
puts "server: message received: #{data}"
|
|
32
|
+
|
|
33
|
+
s.send("hello client!", 0, client)
|
|
34
|
+
|
|
35
|
+
s.close
|
|
36
|
+
|
|
37
|
+
Client:
|
|
38
|
+
|
|
39
|
+
require 'rubygems'
|
|
40
|
+
require 'tipcsocket'
|
|
41
|
+
|
|
42
|
+
include TIPCSocket::Constants
|
|
43
|
+
|
|
44
|
+
server_addr = TIPCName.new(18888, 17, TIPC_NODE_SCOPE)
|
|
45
|
+
|
|
46
|
+
s = TIPCSocket.new(:rdm)
|
|
47
|
+
s.send("hello server!", 0, server_addr)
|
|
48
|
+
|
|
49
|
+
msg = s.recv(65535)
|
|
50
|
+
|
|
51
|
+
puts "client: received response: #{msg}"
|
|
52
|
+
|
|
53
|
+
s.close
|
|
54
|
+
|
|
55
|
+
Server Output:
|
|
56
|
+
|
|
57
|
+
$ ruby server.rb
|
|
58
|
+
#<TIPCPortId:0xb79c89a4 @family=30, @ref=2292940796, @scope=0, @addrtype=3, @node=0>
|
|
59
|
+
server: message received: hello server!
|
|
60
|
+
|
|
61
|
+
Client Output:
|
|
62
|
+
|
|
63
|
+
$ ruby client.rb
|
|
64
|
+
client: received response: hello client!
|
|
65
|
+
|
|
66
|
+
= More Examples
|
|
67
|
+
|
|
68
|
+
See the demo/ directory for more examples.
|
|
69
|
+
|
|
70
|
+
= Project Page
|
|
71
|
+
|
|
72
|
+
http://rubyforge.org/projects/tipcsocket
|
|
73
|
+
|
|
74
|
+
= Author
|
|
75
|
+
|
|
76
|
+
Corey Burrows (mailto:corey.burrows@gmail.com)
|
|
77
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
Gem::manage_gems
|
|
4
|
+
require 'rake/gempackagetask'
|
|
5
|
+
require 'rake/clean'
|
|
6
|
+
require 'rake/rdoctask'
|
|
7
|
+
|
|
8
|
+
NAME = 'tipcsocket'
|
|
9
|
+
VERS = '0.1'
|
|
10
|
+
RUBYFORGE_USER = "burrows"
|
|
11
|
+
WWW = "#{RUBYFORGE_USER}@rubyforge.org:/var/www/gforge-projects/#{NAME}/"
|
|
12
|
+
|
|
13
|
+
RDOC_MAIN = "README"
|
|
14
|
+
|
|
15
|
+
spec = Gem::Specification.new do |s|
|
|
16
|
+
s.name = NAME
|
|
17
|
+
s.version = VERS
|
|
18
|
+
s.author = "Corey Burrows"
|
|
19
|
+
s.email = "corey.burrows@gmail.com"
|
|
20
|
+
s.platform = Gem::Platform::RUBY
|
|
21
|
+
s.summary = "Ruby bindings for the TIPC socket API."
|
|
22
|
+
s.files = %w{README CHANGELOG LICENSE Rakefile} +
|
|
23
|
+
Dir.glob("lib/**/*.{rb}") +
|
|
24
|
+
Dir.glob("test/**/*.rb") +
|
|
25
|
+
Dir.glob("demo/**/*.rb")
|
|
26
|
+
s.require_path = "lib"
|
|
27
|
+
s.autorequire = "tipcsocket"
|
|
28
|
+
#s.test_file = ""
|
|
29
|
+
s.has_rdoc = true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
|
33
|
+
pkg.need_tar = true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
Rake::RDocTask.new do |rd|
|
|
37
|
+
rd.main = RDOC_MAIN
|
|
38
|
+
rd.rdoc_files.include(RDOC_MAIN, "lib/**/*.rb", "CHANGELOG", "LICENSE")
|
|
39
|
+
rd.options << "--all"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
CLEAN += FileList["ext/**/*.o", "ext/**/*.so", "ext/**/*.bundle", "ext/**/mkmf.log"]
|
|
43
|
+
|
|
44
|
+
task :test => :build do
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
task :install do
|
|
48
|
+
name = "#{NAME}-#{VERS}.gem"
|
|
49
|
+
sh %{rake pkg/#{name}}
|
|
50
|
+
sh %{sudo gem install pkg/#{name}}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
task :uninstall do
|
|
54
|
+
sh %{sudo gem uninstall #{NAME}}
|
|
55
|
+
end
|
|
56
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
|
4
|
+
|
|
5
|
+
require 'tipcsocket'
|
|
6
|
+
include TIPCSocket::Constants
|
|
7
|
+
|
|
8
|
+
puts "****** TIPC client hello world program started ******\n"
|
|
9
|
+
|
|
10
|
+
$server_type = 18888
|
|
11
|
+
$server_inst = 17
|
|
12
|
+
|
|
13
|
+
def wait_for_server(name, wait)
|
|
14
|
+
puts "Client: waiting for server #{name.type}, #{name.instance}..."
|
|
15
|
+
|
|
16
|
+
topsrv = TIPCName.new(TIPC_TOP_SRV, TIPC_TOP_SRV)
|
|
17
|
+
subscr = TIPCSubscr.new(
|
|
18
|
+
TIPCNameSeq.new(name.type, name.instance, name.instance),
|
|
19
|
+
wait,
|
|
20
|
+
TIPC_SUB_SERVICE)
|
|
21
|
+
|
|
22
|
+
s = TIPCSocket.new(:seqpacket)
|
|
23
|
+
s.connect(topsrv)
|
|
24
|
+
s.send(subscr.pack, 0)
|
|
25
|
+
|
|
26
|
+
rsp = s.recv(65535)
|
|
27
|
+
|
|
28
|
+
event = TIPCEvent.unpack(rsp)
|
|
29
|
+
|
|
30
|
+
if event.event != TIPC_PUBLISHED
|
|
31
|
+
puts "Client: server #{name.type}, #{name.instance} not published within #{wait/1000} [s]"
|
|
32
|
+
exit 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
s.close
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
s = TIPCSocket.new(:rdm)
|
|
39
|
+
|
|
40
|
+
# send a message to the server
|
|
41
|
+
server_addr = TIPCName.new($server_type, $server_inst, TIPC_NODE_SCOPE)
|
|
42
|
+
|
|
43
|
+
wait_for_server(server_addr, 10000)
|
|
44
|
+
|
|
45
|
+
s.send("Hello World", 0, server_addr)
|
|
46
|
+
|
|
47
|
+
# wait for a response
|
|
48
|
+
msg = s.recv(65535)
|
|
49
|
+
|
|
50
|
+
puts "Client: Received response: #{msg}"
|
|
51
|
+
|
|
52
|
+
s.close
|
|
53
|
+
|
|
54
|
+
puts "****** TIPC client hello program finished ******"
|
|
55
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
|
4
|
+
|
|
5
|
+
require 'tipcsocket'
|
|
6
|
+
include TIPCSocket::Constants
|
|
7
|
+
|
|
8
|
+
$server_type = 18888
|
|
9
|
+
$server_inst = 17
|
|
10
|
+
|
|
11
|
+
puts "****** TIPC server hello world program started ******\n\n"
|
|
12
|
+
|
|
13
|
+
server_addr = TIPCNameSeq.new($server_type, $server_inst, $server_inst, TIPC_ZONE_SCOPE)
|
|
14
|
+
|
|
15
|
+
s = TIPCSocket.new(:rdm)
|
|
16
|
+
s.bind(server_addr)
|
|
17
|
+
|
|
18
|
+
data, client = s.recvfrom(65535)
|
|
19
|
+
|
|
20
|
+
client = TIPCSocket.unpack_sockaddr(client)
|
|
21
|
+
|
|
22
|
+
puts "Server: Message received: #{data} !"
|
|
23
|
+
|
|
24
|
+
s.send("Uh ?", 0, client)
|
|
25
|
+
|
|
26
|
+
s.close
|
|
27
|
+
|
|
28
|
+
puts "\n****** TIPC server hello program finished ******"
|
|
29
|
+
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
|
4
|
+
|
|
5
|
+
require 'tipcsocket'
|
|
6
|
+
include TIPCSocket::Constants
|
|
7
|
+
|
|
8
|
+
$server_type = 8888
|
|
9
|
+
$server_inst = 17
|
|
10
|
+
|
|
11
|
+
$buf_size = 2000
|
|
12
|
+
$msg_size = 80
|
|
13
|
+
|
|
14
|
+
def wait_for_server(name, wait)
|
|
15
|
+
puts "Client: waiting for server #{name.type}, #{name.instance}..."
|
|
16
|
+
|
|
17
|
+
topsrv = TIPCName.new(TIPC_TOP_SRV, TIPC_TOP_SRV)
|
|
18
|
+
subscr = TIPCSubscr.new(
|
|
19
|
+
TIPCNameSeq.new(name.type, name.instance, name.instance),
|
|
20
|
+
wait,
|
|
21
|
+
TIPC_SUB_SERVICE)
|
|
22
|
+
|
|
23
|
+
s = TIPCSocket.new(:seqpacket)
|
|
24
|
+
s.connect(topsrv)
|
|
25
|
+
s.send(subscr.pack, 0)
|
|
26
|
+
|
|
27
|
+
rsp = s.recv(65535)
|
|
28
|
+
|
|
29
|
+
event = TIPCEvent.unpack(rsp)
|
|
30
|
+
|
|
31
|
+
if event.event != TIPC_PUBLISHED
|
|
32
|
+
puts "Client: server #{name.type}, #{name.instance} not published within #{wait/1000} [s]"
|
|
33
|
+
exit 1
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
s.close
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
puts "****** TIPC stream demo client started ******"
|
|
40
|
+
|
|
41
|
+
server_addr = TIPCName.new($server_type, $server_inst)
|
|
42
|
+
|
|
43
|
+
wait_for_server(server_addr, 10000)
|
|
44
|
+
|
|
45
|
+
s = TIPCSocket.new(:stream)
|
|
46
|
+
|
|
47
|
+
begin
|
|
48
|
+
s.connect(server_addr)
|
|
49
|
+
rescue Exception => e
|
|
50
|
+
puts "Client: connect failed: #{e}"
|
|
51
|
+
exit 1
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# create buffer containing numerous (size,data) records
|
|
55
|
+
|
|
56
|
+
tot_size = 0
|
|
57
|
+
rec_size = 1
|
|
58
|
+
rec_num = 0
|
|
59
|
+
buf = ""
|
|
60
|
+
|
|
61
|
+
while tot_size + 4 + rec_size < $buf_size
|
|
62
|
+
rec_num += 1
|
|
63
|
+
buf += [rec_size].pack("N")
|
|
64
|
+
rec_size.times do
|
|
65
|
+
buf += [rec_size].pack("C")
|
|
66
|
+
end
|
|
67
|
+
puts "Client: creating record #{rec_num} of size #{rec_size} bytes"
|
|
68
|
+
|
|
69
|
+
tot_size += (4 + rec_size)
|
|
70
|
+
rec_size = (rec_size + 147) & 0xFF;
|
|
71
|
+
|
|
72
|
+
rec_size = 1 if (rec_size == 0) # record size must me 1-255 bytes
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# now send records using messages that break record boundaries
|
|
76
|
+
|
|
77
|
+
puts "Client: sending records using #{$msg_size} byte messages"
|
|
78
|
+
|
|
79
|
+
sent_size = 0
|
|
80
|
+
while sent_size < tot_size
|
|
81
|
+
if (sent_size + $msg_size) <= tot_size
|
|
82
|
+
msg_size = $msg_size
|
|
83
|
+
else
|
|
84
|
+
msg_size = (tot_size - sent_size)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if (0 > s.send(buf[sent_size, msg_size], 0))
|
|
88
|
+
puts "Client: failed to send"
|
|
89
|
+
exit 1
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
sent_size += msg_size
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# now grab set of one-byte client acknowledgements all at once
|
|
96
|
+
|
|
97
|
+
puts "Client: waiting for server acknowledgements"
|
|
98
|
+
rsp = s.recv(rec_num, Socket::MSG_WAITALL)
|
|
99
|
+
if rsp.length != rec_num
|
|
100
|
+
puts "Client: acknowledge error 1"
|
|
101
|
+
exit 1
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
rsp = nil
|
|
105
|
+
begin
|
|
106
|
+
rsp = s.recv_nonblock(1)
|
|
107
|
+
rescue Errno::EAGAIN => e
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
if rsp
|
|
111
|
+
puts "Client: acknowledge error 2"
|
|
112
|
+
exit 1
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
puts "Client: received #{rec_num} acknowledgements"
|
|
116
|
+
|
|
117
|
+
s.shutdown(Socket::SHUT_RDWR)
|
|
118
|
+
s.close
|
|
119
|
+
|
|
120
|
+
puts "****** TIPC stream demo client finished ******"
|
|
121
|
+
exit 0
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
|
4
|
+
|
|
5
|
+
require 'tipcsocket'
|
|
6
|
+
include TIPCSocket::Constants
|
|
7
|
+
|
|
8
|
+
$server_type = 8888
|
|
9
|
+
$server_inst = 17
|
|
10
|
+
|
|
11
|
+
puts "****** TIPC stream demo server started ******"
|
|
12
|
+
|
|
13
|
+
listener = TIPCSocket.new(:stream)
|
|
14
|
+
|
|
15
|
+
server_addr = TIPCNameSeq.new($server_type, $server_inst, $server_inst, TIPC_ZONE_SCOPE)
|
|
16
|
+
|
|
17
|
+
listener.bind(server_addr)
|
|
18
|
+
listener.listen(0)
|
|
19
|
+
|
|
20
|
+
peer, peer_addr = listener.accept
|
|
21
|
+
|
|
22
|
+
rec_num = 0
|
|
23
|
+
|
|
24
|
+
loop do
|
|
25
|
+
begin
|
|
26
|
+
puts "calling peer.recv..."
|
|
27
|
+
msg = peer.recv(4, Socket::MSG_WAITALL)
|
|
28
|
+
puts "recieved #{msg.length} bytes"
|
|
29
|
+
rescue Exception => e
|
|
30
|
+
puts "Server: client terminated abnormally: #{e}"
|
|
31
|
+
exit 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if msg.length == 0
|
|
35
|
+
puts "Server: client terminated normally"
|
|
36
|
+
break
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
rec_num += 1
|
|
40
|
+
|
|
41
|
+
rec_size = msg.unpack("N")[0]
|
|
42
|
+
puts "Server: receiving record #{rec_num} of #{rec_size} bytes"
|
|
43
|
+
|
|
44
|
+
msg = peer.recv(rec_size, Socket::MSG_WAITALL)
|
|
45
|
+
|
|
46
|
+
if msg.length != rec_size
|
|
47
|
+
puts "Server: receive error, got #{msg.length} bytes"
|
|
48
|
+
exit 1
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
msg.each_byte do |b|
|
|
52
|
+
if b != rec_size
|
|
53
|
+
puts "Server: record content error"
|
|
54
|
+
exit 1
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
puts "Server: record #{rec_num} received"
|
|
59
|
+
|
|
60
|
+
# send 1 byte acknowledgement (value is irrelevant)
|
|
61
|
+
peer.send("X", 0)
|
|
62
|
+
|
|
63
|
+
puts "Server: record #{rec_num} acknowledged"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
puts "****** TIPC stream demo server finished ******"
|
|
67
|
+
|
|
68
|
+
exit 0
|
|
69
|
+
|
data/lib/tipcsocket.rb
ADDED
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
|
|
2
|
+
require 'socket'
|
|
3
|
+
|
|
4
|
+
module Socket::Constants
|
|
5
|
+
AF_TIPC = 30
|
|
6
|
+
PF_TIPC = AF_TIPC
|
|
7
|
+
SOL_TIPC = 271
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Represents a TIPC port identifier.
|
|
11
|
+
#
|
|
12
|
+
# From the {TIPC Programmer's Guide}[http://tipc.sourceforge.net/doc/Programmers_Guide.txt]:
|
|
13
|
+
#
|
|
14
|
+
# Each port in a TIPC network has a unique "port identifier" or "port ID",
|
|
15
|
+
# which is typically denoted as <Z.C.N:ref>. The port ID is assigned
|
|
16
|
+
# automatically by TIPC when the port is created, and consists of the 32-bit
|
|
17
|
+
# network address of the port's node and a 32-bit reference value. The
|
|
18
|
+
# reference value is guaranteed to be unique on a per-node basis and will not
|
|
19
|
+
# be reused for a long time once the port ceases to exist.
|
|
20
|
+
class TIPCPortId
|
|
21
|
+
attr_reader :family, :addrtype
|
|
22
|
+
attr_accessor :ref, :node, :scope
|
|
23
|
+
|
|
24
|
+
# Create a new TIPCPortId instance.
|
|
25
|
+
#
|
|
26
|
+
# === Parameters
|
|
27
|
+
# * ref - 32 bit reference value
|
|
28
|
+
# * node - 32 bit network address of the port's node
|
|
29
|
+
# * scope - the scope (zone, cluster, or node) to use when packing this port
|
|
30
|
+
# id as a TIPC address (optional)
|
|
31
|
+
def initialize(ref, node, scope = TIPCSocket::Constants::TIPC_NODE_SCOPE)
|
|
32
|
+
@family = Socket::Constants::AF_TIPC
|
|
33
|
+
@addrtype = TIPCSocket::Constants::TIPC_ADDR_ID
|
|
34
|
+
@ref = ref
|
|
35
|
+
@node = node
|
|
36
|
+
@scope = scope
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Pack an instance of a TIPCPortId as a 16 byte TIPC network address suitable
|
|
40
|
+
# for passing to one of the standard Socket methods (connect, send, etc.).
|
|
41
|
+
#
|
|
42
|
+
# Produces a 16 byte binary string with the following format:
|
|
43
|
+
# * family - unsigned short (2 bytes)
|
|
44
|
+
# * addrtype - unsigned char (1 byte)
|
|
45
|
+
# * scope - signed char (1 byte)
|
|
46
|
+
# * ref - uint32 (4 bytes)
|
|
47
|
+
# * node - uint32 (4 bytes)
|
|
48
|
+
# * padding - uint32 (4 bytes)
|
|
49
|
+
def pack_addr
|
|
50
|
+
[
|
|
51
|
+
self.family,
|
|
52
|
+
self.addrtype,
|
|
53
|
+
self.scope,
|
|
54
|
+
self.ref,
|
|
55
|
+
self.node,
|
|
56
|
+
0
|
|
57
|
+
].pack("SCcL3")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Pack an instance of a TIPCPortId.
|
|
61
|
+
#
|
|
62
|
+
# Produces an 8 byte string with the following format:
|
|
63
|
+
# * ref - uint32 (4 bytes)
|
|
64
|
+
# * node - uint32 (4 bytes)
|
|
65
|
+
def pack
|
|
66
|
+
[
|
|
67
|
+
self.ref,
|
|
68
|
+
self.node,
|
|
69
|
+
].pack("L2")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Create a new TIPCPortId instance from a 16 byte binary string containing a
|
|
73
|
+
# TIPC address.
|
|
74
|
+
#
|
|
75
|
+
# === Parameters
|
|
76
|
+
# * bytes - 16 byte string containing TIPC address
|
|
77
|
+
def self.unpack_addr(bytes)
|
|
78
|
+
data = bytes.unpack("SCcL3")
|
|
79
|
+
self.new(data[3], data[4], data[2])
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Create a new TIPCPortId instance from an 8 byte binary string containing
|
|
83
|
+
# a TIPC port indentifier.
|
|
84
|
+
#
|
|
85
|
+
# === Parameters
|
|
86
|
+
# * bytes - 8 byte string containing TIPC port identifier
|
|
87
|
+
def self.unpack(bytes)
|
|
88
|
+
data = bytes.unpack("L2")
|
|
89
|
+
self.new(data[0], data[1])
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Represents a TIPC name address of the form <type, instance>.
|
|
94
|
+
#
|
|
95
|
+
# From the {TIPC Programmer's Guide}[http://tipc.sourceforge.net/doc/Programmers_Guide.txt]:
|
|
96
|
+
#
|
|
97
|
+
# The basic unit of functional addressing within TIPC is the "port name", which
|
|
98
|
+
# is typically denoted as {type,instance}. A port name consists of a 32-bit
|
|
99
|
+
# type field and a 32-bit instance field, both of which are chosen by the
|
|
100
|
+
# application. Typically, the type field is used to indicate the class of
|
|
101
|
+
# service provided by the port, while the instance field can be used as a sub-
|
|
102
|
+
# class indicator.
|
|
103
|
+
class TIPCName
|
|
104
|
+
attr_reader :family, :addrtype
|
|
105
|
+
attr_accessor :type, :instance, :scope, :domain
|
|
106
|
+
|
|
107
|
+
# Create a new TIPCName instance.
|
|
108
|
+
#
|
|
109
|
+
# === Parameters
|
|
110
|
+
# * type - arbitrary 32 bit type value
|
|
111
|
+
# * instance - arbitrary 32 bit instance value
|
|
112
|
+
# * scope - the scope (zone, cluster, or node) to use when packing
|
|
113
|
+
# this name as a TIPC address (optional)
|
|
114
|
+
# * domain - indicates the search domain used during the name lookup
|
|
115
|
+
# process (optional)
|
|
116
|
+
def initialize(type, instance, scope = TIPCSocket::Constants::TIPC_NODE_SCOPE, domain = 0)
|
|
117
|
+
@family = Socket::Constants::AF_TIPC
|
|
118
|
+
@addrtype = TIPCSocket::Constants::TIPC_ADDR_NAME
|
|
119
|
+
@type = type
|
|
120
|
+
@instance = instance
|
|
121
|
+
@scope = scope
|
|
122
|
+
@domain = 0
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Pack an instance of a TIPCName as a 16 byte TIPC network address suitable
|
|
126
|
+
# for passing to one of the standard Socket methods (connect, send, etc.).
|
|
127
|
+
#
|
|
128
|
+
# Produces a 16 byte binary string with the following format:
|
|
129
|
+
# * family - unsigned short (2 bytes)
|
|
130
|
+
# * addrtype - unsigned char (1 byte)
|
|
131
|
+
# * scope - signed char (1 byte)
|
|
132
|
+
# * type - uint32 (4 bytes)
|
|
133
|
+
# * instance - uint32 (4 bytes)
|
|
134
|
+
# * domain - uint32 (4 bytes)
|
|
135
|
+
def pack_addr
|
|
136
|
+
[
|
|
137
|
+
self.family,
|
|
138
|
+
self.addrtype,
|
|
139
|
+
self.scope,
|
|
140
|
+
self.type,
|
|
141
|
+
self.instance,
|
|
142
|
+
self.domain
|
|
143
|
+
].pack("SCcL3")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Pack an instance of a TIPCName.
|
|
147
|
+
#
|
|
148
|
+
# Produces an 8 byte string with the following format:
|
|
149
|
+
# * type - uint32 (4 bytes)
|
|
150
|
+
# * instance - uint32 (4 bytes)
|
|
151
|
+
def pack
|
|
152
|
+
[
|
|
153
|
+
self.type,
|
|
154
|
+
self.instance
|
|
155
|
+
].pack("L2")
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Create a new TIPCName instance from a 16 byte binary string containing a
|
|
159
|
+
# TIPC address.
|
|
160
|
+
#
|
|
161
|
+
# === Parameters
|
|
162
|
+
# * bytes - 16 byte string containing TIPC address
|
|
163
|
+
def self.unpack_addr(bytes)
|
|
164
|
+
data = bytes.unpack("SCcL3")
|
|
165
|
+
self.new(data[3], data[4], data[2], data[5])
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Create a new TIPCName instance from an 8 byte binary string containing
|
|
169
|
+
# a TIPC name.
|
|
170
|
+
#
|
|
171
|
+
# === Parameters
|
|
172
|
+
# * bytes - 8 byte string containing TIPC name
|
|
173
|
+
def self.unpack(bytes)
|
|
174
|
+
data = bytes.unpack("L2")
|
|
175
|
+
self.new(data[0], data[1])
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Represents a TIPC port name sequence address of the form
|
|
180
|
+
# <type, lower bound, upper bound>.
|
|
181
|
+
#
|
|
182
|
+
# From the {TIPC Programmer's Guide}[http://tipc.sourceforge.net/doc/Programmers_Guide.txt]:
|
|
183
|
+
#
|
|
184
|
+
# A port name sequence consists of a 32-bit type field and a pair of 32-bit
|
|
185
|
+
# instance fields, and represents the set of port names from {type,lower bound}
|
|
186
|
+
# through {type,upper bound}, inclusive. The lower bound of a name sequence
|
|
187
|
+
# cannot be larger than the upper bound.
|
|
188
|
+
class TIPCNameSeq
|
|
189
|
+
attr_reader :family, :addrtype
|
|
190
|
+
attr_accessor :type, :lower, :upper, :scope
|
|
191
|
+
|
|
192
|
+
# Create a new TIPCNameSeq instance.
|
|
193
|
+
#
|
|
194
|
+
# === Parameters
|
|
195
|
+
# * type - arbitrary 32 bit type value
|
|
196
|
+
# * lower - 32-bit lower bound of the name sequence
|
|
197
|
+
# * upper - 32-bit upper bound of the name sequence
|
|
198
|
+
# * scope - the scope (zone, cluster, or node) to use when packing
|
|
199
|
+
# this name as a TIPC address (optional)
|
|
200
|
+
def initialize(type, lower, upper, scope = TIPCSocket::Constants::TIPC_NODE_SCOPE)
|
|
201
|
+
@family = Socket::Constants::AF_TIPC
|
|
202
|
+
@addrtype = TIPCSocket::Constants::TIPC_ADDR_NAMESEQ
|
|
203
|
+
@type = type
|
|
204
|
+
@lower = lower
|
|
205
|
+
@upper = upper
|
|
206
|
+
@scope = scope
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Pack an instance of a TIPCNameSeq as a 16 byte TIPC network address suitable
|
|
210
|
+
# for passing to one of the standard Socket methods (connect, send, etc.).
|
|
211
|
+
#
|
|
212
|
+
# Produces a 16 byte binary string with the following format:
|
|
213
|
+
# * family - unsigned short (2 bytes)
|
|
214
|
+
# * addrtype - unsigned char (1 byte)
|
|
215
|
+
# * scope - signed char (1 byte)
|
|
216
|
+
# * type - uint32 (4 bytes)
|
|
217
|
+
# * lower - uint32 (4 bytes)
|
|
218
|
+
# * upper - uint32 (4 bytes)
|
|
219
|
+
def pack_addr
|
|
220
|
+
[
|
|
221
|
+
self.family,
|
|
222
|
+
self.addrtype,
|
|
223
|
+
self.scope,
|
|
224
|
+
self.type,
|
|
225
|
+
self.lower,
|
|
226
|
+
self.upper
|
|
227
|
+
].pack("SCcL3")
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Pack an instance of a TIPCNameSeq.
|
|
231
|
+
#
|
|
232
|
+
# Produces an 12 byte string with the following format:
|
|
233
|
+
# * type - uint32 (4 bytes)
|
|
234
|
+
# * lower - uint32 (4 bytes)
|
|
235
|
+
# * upper - uint32 (4 bytes)
|
|
236
|
+
def pack
|
|
237
|
+
[
|
|
238
|
+
self.type,
|
|
239
|
+
self.lower,
|
|
240
|
+
self.upper
|
|
241
|
+
].pack("L3")
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Create a new TIPCNameSeq instance from a 16 byte binary string containing a
|
|
245
|
+
# TIPC address.
|
|
246
|
+
#
|
|
247
|
+
# === Parameters
|
|
248
|
+
# * bytes - 16 byte string containing TIPC address
|
|
249
|
+
def self.unpack_addr(bytes)
|
|
250
|
+
data = bytes.unpack("SCcL3")
|
|
251
|
+
self.new(data[3], data[4], data[5], data[2])
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# Create a new TIPCNameSeq instance from a 12 byte binary string containing
|
|
255
|
+
# a TIPC name sequence.
|
|
256
|
+
#
|
|
257
|
+
# === Parameters
|
|
258
|
+
# * bytes - 12 byte string containing TIPC name sequence
|
|
259
|
+
def self.unpack(bytes)
|
|
260
|
+
data = bytes.unpack("L3")
|
|
261
|
+
self.new(data[0], data[1], data[2])
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# Represents a TIPC subscription.
|
|
266
|
+
#
|
|
267
|
+
# From the {TIPC Programmer's Guide}[http://tipc.sourceforge.net/doc/Programmers_Guide.txt]:
|
|
268
|
+
#
|
|
269
|
+
# TIPC provides a network topology service that applications can use to receive
|
|
270
|
+
# information about what port names exist within the application's network zone.
|
|
271
|
+
#
|
|
272
|
+
# An application accesses the topology service by opening a message-based
|
|
273
|
+
# connection to port name {1,1} and then sending "subscription" messages to the
|
|
274
|
+
# topology service that indicate the port names of interest to the application;
|
|
275
|
+
# in return, the topology service sends "event" messages to the application when
|
|
276
|
+
# these names are published or withdrawn by ports within the network.
|
|
277
|
+
class TIPCSubscr
|
|
278
|
+
attr_accessor :name_seq, :timeout, :filter, :usr_handle
|
|
279
|
+
|
|
280
|
+
# Create a new TIPCSubscr instance.
|
|
281
|
+
#
|
|
282
|
+
# === Parameters
|
|
283
|
+
# * name_seq - the port name sequence of interest, must be an instance of
|
|
284
|
+
# TIPCNameSeq
|
|
285
|
+
# * timeout - subscription timeout value in milliseconds, use the constant
|
|
286
|
+
# TIPC_WAIT_FOREVER to specify no timeout
|
|
287
|
+
# * filter - a bitmask containing one or more event filters, see below
|
|
288
|
+
# for a description of filter types
|
|
289
|
+
# * usr_handle - 8 byte string that is application defined, this value is
|
|
290
|
+
# returned to the application as part of all events associated
|
|
291
|
+
# with the subscription event
|
|
292
|
+
#
|
|
293
|
+
# === Filter Types
|
|
294
|
+
# * TIPC_SUB_PORTS - causes the topology service to generate a TIPC_PUBLISHED
|
|
295
|
+
# event for each port name or port name sequence it finds
|
|
296
|
+
# that overlaps the specified port name sequence; a
|
|
297
|
+
# TIPC_WITHDRAWN event is issued each time a previously
|
|
298
|
+
# reported name becomes unavailable
|
|
299
|
+
# * TIPC_SUB_SERVICE - causes the topology service to generate a single publish
|
|
300
|
+
# event for the first port it finds with an overlapping
|
|
301
|
+
# name and a single withdraw event when the last such port
|
|
302
|
+
# becomes unavailable
|
|
303
|
+
# * TIPC_SUB_CANCEL - cancels and existing topology service subscription, all
|
|
304
|
+
# other parameters should match the original subscription
|
|
305
|
+
# request
|
|
306
|
+
def initialize(name_seq, timeout, filter, usr_handle = '')
|
|
307
|
+
@name_seq = name_seq
|
|
308
|
+
@timeout = timeout
|
|
309
|
+
@filter = filter
|
|
310
|
+
@usr_handle = usr_handle
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Pack an instance of a TIPCSubscr.
|
|
314
|
+
#
|
|
315
|
+
# Produces a 28 byte string with the following format:
|
|
316
|
+
# * name_seq (12 bytes)
|
|
317
|
+
# * timeout - uint32 (4 bytes)
|
|
318
|
+
# * filter - uint32 (4 bytes)
|
|
319
|
+
# * usr_handle - char[8] (8 bytes)
|
|
320
|
+
def pack
|
|
321
|
+
[
|
|
322
|
+
self.name_seq.pack,
|
|
323
|
+
self.timeout,
|
|
324
|
+
self.filter,
|
|
325
|
+
self.usr_handle
|
|
326
|
+
].pack("a12L2a8")
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Create a new TIPCSubscr instance from a 28 byte binary string containing
|
|
330
|
+
# a TIPC name sequence.
|
|
331
|
+
#
|
|
332
|
+
# === Parameters
|
|
333
|
+
# * bytes - 28 byte string containing TIPC name sequence
|
|
334
|
+
def self.unpack(bytes)
|
|
335
|
+
data = bytes.unpack("a12L2a8")
|
|
336
|
+
self.new(TIPCNameSeq.unpack(data[0]), data[1], data[2], data[3])
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# Represents a TIPC event message.
|
|
341
|
+
#
|
|
342
|
+
# TIPC event messages are returned by the TIPC topology server when subscribed
|
|
343
|
+
# to events occur.
|
|
344
|
+
class TIPCEvent
|
|
345
|
+
attr_accessor :event, :found_lower, :found_upper, :port, :subscr
|
|
346
|
+
|
|
347
|
+
# Create a new TIPCEvent instance.
|
|
348
|
+
#
|
|
349
|
+
# === Parameters
|
|
350
|
+
# * event - 32-bit event type, may be either TIPC_PUBLISHED, TIPC_WITHDRAWN,
|
|
351
|
+
# or TIPC_SUBSCR_TIMEOUT
|
|
352
|
+
# * found_lower - 32-bit lower bound of the port name sequence that overlaps
|
|
353
|
+
# the name sequence specified by the subscription
|
|
354
|
+
# * found_upper - 32-bit upper bound of the port name sequence that overlaps
|
|
355
|
+
# the name sequence specified by the subscription
|
|
356
|
+
# * port - an instance of TIPCPortId that represents the port ID of the
|
|
357
|
+
# associated port
|
|
358
|
+
# * subscr - an instance of TIPCSubscr that represents the subscription
|
|
359
|
+
# request associated with the event
|
|
360
|
+
def initialize(event, found_lower, found_upper, port, subscr)
|
|
361
|
+
@event = event
|
|
362
|
+
@found_lower = found_lower
|
|
363
|
+
@found_upper = found_upper
|
|
364
|
+
@port = port
|
|
365
|
+
@subscr = subscr
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# Pack an instance of a TIPCEvent.
|
|
369
|
+
#
|
|
370
|
+
# Produces an 48 byte string with the following format:
|
|
371
|
+
# * event - uint32 = 4
|
|
372
|
+
# * found_lower - uint32 = 4
|
|
373
|
+
# * found_upper - uint32 = 4
|
|
374
|
+
# * port_id = 8
|
|
375
|
+
# * subscr = 28
|
|
376
|
+
def pack
|
|
377
|
+
[
|
|
378
|
+
self.event,
|
|
379
|
+
self.found_lower,
|
|
380
|
+
self.found_upper,
|
|
381
|
+
port.pack,
|
|
382
|
+
subscr.pack
|
|
383
|
+
].pack("L3a8a28")
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# Create a new TIPCEvent instance from a 48 byte binary string containing a
|
|
387
|
+
# TIPC event.
|
|
388
|
+
#
|
|
389
|
+
# === Parameters
|
|
390
|
+
# * bytes - 48 byte string containing TIPC address
|
|
391
|
+
def self.unpack(bytes)
|
|
392
|
+
data = bytes.unpack("L3a8a28")
|
|
393
|
+
self.new(data[0], data[1], data[2], TIPCPortId.unpack(data[3]),
|
|
394
|
+
TIPCSubscr.unpack(data[4]))
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
# Provides access to a TIPC[http://tipc.sourceforge.net] socket. Subclass of
|
|
399
|
+
# the standard ruby Socket class.
|
|
400
|
+
class TIPCSocket < Socket
|
|
401
|
+
module Constants
|
|
402
|
+
# application accessible port name types
|
|
403
|
+
TIPC_CFG_SRV = 0
|
|
404
|
+
TIPC_TOP_SRV = 1
|
|
405
|
+
TIPC_RESERVED_TYPES = 64
|
|
406
|
+
|
|
407
|
+
# publication scopes when binding port names and port name sequences
|
|
408
|
+
TIPC_ZONE_SCOPE = 1
|
|
409
|
+
TIPC_CLUSTER_SCOPE = 2
|
|
410
|
+
TIPC_NODE_SCOPE = 3
|
|
411
|
+
|
|
412
|
+
# limiting values for messages
|
|
413
|
+
TIPC_MAX_USER_MSG_SIZE = 66000
|
|
414
|
+
|
|
415
|
+
# message importance levels
|
|
416
|
+
TIPC_LOW_IMPORTANCE = 0
|
|
417
|
+
TIPC_MEDIUM_IMPORTANCE = 1
|
|
418
|
+
TIPC_HIGH_IMPORTANCE = 2
|
|
419
|
+
TIPC_CRITICAL_IMPORTANCE = 3
|
|
420
|
+
|
|
421
|
+
# message rejection/connection shutdown reasons
|
|
422
|
+
TIPC_OK = 0
|
|
423
|
+
TIPC_ERR_NO_NAME = 1
|
|
424
|
+
TIPC_ERR_NO_PORT = 2
|
|
425
|
+
TIPC_ERR_NO_NODE = 3
|
|
426
|
+
TIPC_ERR_OVERLOAD = 4
|
|
427
|
+
TIPC_CONN_SHUTDOWN = 5
|
|
428
|
+
|
|
429
|
+
# topology subscription service definitions
|
|
430
|
+
TIPC_SUB_PORTS = 0x01
|
|
431
|
+
TIPC_SUB_SERVICE = 0x02
|
|
432
|
+
TIPC_SUB_CANCEL = 0x04
|
|
433
|
+
|
|
434
|
+
TIPC_WAIT_FOREVER = -1
|
|
435
|
+
|
|
436
|
+
# address types
|
|
437
|
+
TIPC_ADDR_NAMESEQ = 1
|
|
438
|
+
TIPC_ADDR_MCAST = 1
|
|
439
|
+
TIPC_ADDR_NAME = 2
|
|
440
|
+
TIPC_ADDR_ID = 3
|
|
441
|
+
|
|
442
|
+
# events
|
|
443
|
+
TIPC_PUBLISHED = 1
|
|
444
|
+
TIPC_WITHDRAWN = 2
|
|
445
|
+
TIPC_SUBSCR_TIMEOUT = 3
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
# Create a new TIPCSocket instance from a 16 byte binary string containing a
|
|
449
|
+
# TIPC address. Returns one of the following depending on the addrtype
|
|
450
|
+
# field: TIPCNameSeq, TIPCName, TIPCPortId.
|
|
451
|
+
#
|
|
452
|
+
# === Parameters
|
|
453
|
+
# * bytes - 16 byte string containing TIPC address
|
|
454
|
+
def self.unpack_sockaddr(bytes)
|
|
455
|
+
family, addrtype = bytes.unpack("SC")
|
|
456
|
+
|
|
457
|
+
case
|
|
458
|
+
when addrtype == Constants::TIPC_ADDR_NAMESEQ
|
|
459
|
+
TIPCNameSeq.unpack_addr(bytes)
|
|
460
|
+
when addrtype == Constants::TIPC_ADDR_NAME
|
|
461
|
+
TIPCName.unpack_addr(bytes)
|
|
462
|
+
when addrtype == Constants::TIPC_ADDR_ID
|
|
463
|
+
TIPCPortId.unpack_addr(bytes)
|
|
464
|
+
else
|
|
465
|
+
raise ArgumentError, "invalid address type (#{addrtype})"
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
# Create a new instance of a TIPCSocket.
|
|
470
|
+
#
|
|
471
|
+
# === Parameters
|
|
472
|
+
# - type: must be one of the following
|
|
473
|
+
# * :stream - for reliable connection-oriented byte streams
|
|
474
|
+
# * :seqpacket - for reliable connection-oriented messages
|
|
475
|
+
# * :rdm - for reliable connectionless messages
|
|
476
|
+
# * :dgram - for unreliable connectionless messages
|
|
477
|
+
# - protocol: passed directly to Socket.new (optional)
|
|
478
|
+
def initialize(type, protocol = 0)
|
|
479
|
+
case type.to_s.downcase
|
|
480
|
+
when 'stream'
|
|
481
|
+
type = Socket::Constants::SOCK_STREAM
|
|
482
|
+
when 'seqpacket'
|
|
483
|
+
type = Socket::Constants::SOCK_SEQPACKET
|
|
484
|
+
when 'rdm'
|
|
485
|
+
type = Socket::Constants::SOCK_RDM
|
|
486
|
+
when 'dgram'
|
|
487
|
+
type = Socket::Constants::SOCK_DGRAM
|
|
488
|
+
else
|
|
489
|
+
raise TypeError, "invalid TIPC socket type (#{type})"
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
super(Socket::Constants::AF_TIPC, type, protocol)
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def send(msg, flags, tipc_addr = nil)
|
|
496
|
+
if tipc_addr
|
|
497
|
+
tipc_addr = tipc_addr.is_a?(String) ? tipc_addr : tipc_addr.pack_addr
|
|
498
|
+
super(msg, flags, tipc_addr)
|
|
499
|
+
else
|
|
500
|
+
super(msg, flags)
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def bind(tipc_addr)
|
|
505
|
+
tipc_addr = tipc_addr.is_a?(String) ? tipc_addr : tipc_addr.pack_addr
|
|
506
|
+
super(tipc_addr)
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
def connect(tipc_addr)
|
|
510
|
+
tipc_addr = tipc_addr.is_a?(String) ? tipc_addr : tipc_addr.pack_addr
|
|
511
|
+
super(tipc_addr)
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
|
metadata
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
rubygems_version: 0.9.4
|
|
3
|
+
specification_version: 1
|
|
4
|
+
name: tipcsocket
|
|
5
|
+
version: !ruby/object:Gem::Version
|
|
6
|
+
version: "0.1"
|
|
7
|
+
date: 2008-01-14 00:00:00 -06:00
|
|
8
|
+
summary: Ruby bindings for the TIPC socket API.
|
|
9
|
+
require_paths:
|
|
10
|
+
- lib
|
|
11
|
+
email: corey.burrows@gmail.com
|
|
12
|
+
homepage:
|
|
13
|
+
rubyforge_project:
|
|
14
|
+
description:
|
|
15
|
+
autorequire: tipcsocket
|
|
16
|
+
default_executable:
|
|
17
|
+
bindir: bin
|
|
18
|
+
has_rdoc: true
|
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">"
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: 0.0.0
|
|
24
|
+
version:
|
|
25
|
+
platform: ruby
|
|
26
|
+
signing_key:
|
|
27
|
+
cert_chain:
|
|
28
|
+
post_install_message:
|
|
29
|
+
authors:
|
|
30
|
+
- Corey Burrows
|
|
31
|
+
files:
|
|
32
|
+
- README
|
|
33
|
+
- CHANGELOG
|
|
34
|
+
- LICENSE
|
|
35
|
+
- Rakefile
|
|
36
|
+
- lib/tipcsocket.rb
|
|
37
|
+
- demo/hello_world/client.rb
|
|
38
|
+
- demo/hello_world/server.rb
|
|
39
|
+
- demo/stream_demo/client.rb
|
|
40
|
+
- demo/stream_demo/server.rb
|
|
41
|
+
test_files: []
|
|
42
|
+
|
|
43
|
+
rdoc_options: []
|
|
44
|
+
|
|
45
|
+
extra_rdoc_files: []
|
|
46
|
+
|
|
47
|
+
executables: []
|
|
48
|
+
|
|
49
|
+
extensions: []
|
|
50
|
+
|
|
51
|
+
requirements: []
|
|
52
|
+
|
|
53
|
+
dependencies: []
|
|
54
|
+
|