UPnP 1.0.0 → 1.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.tar.gz.sig +0 -0
- data/.autotest +9 -0
- data/History.txt +8 -0
- data/Manifest.txt +8 -0
- data/README.txt +18 -7
- data/Rakefile +3 -0
- data/lib/UPnP.rb +1 -1
- data/lib/UPnP/SSDP.rb +288 -25
- data/lib/UPnP/UUID.rb +187 -0
- data/lib/UPnP/control/service.rb +4 -1
- data/lib/UPnP/device.rb +692 -0
- data/lib/UPnP/root_server.rb +143 -0
- data/lib/UPnP/service.rb +376 -0
- data/test/test_UPnP_SSDP.rb +80 -17
- data/test/test_UPnP_SSDP_response.rb +2 -0
- data/test/test_UPnP_SSDP_search.rb +25 -0
- data/test/test_UPnP_control_device.rb +2 -0
- data/test/test_UPnP_control_service.rb +2 -0
- data/test/test_UPnP_device.rb +295 -0
- data/test/test_UPnP_root_server.rb +99 -0
- data/test/test_UPnP_service.rb +171 -0
- data/test/utilities.rb +61 -14
- metadata +36 -4
- metadata.gz.sig +0 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'test/utilities'
|
4
|
+
require 'UPnP/root_server'
|
5
|
+
|
6
|
+
class TestUPnPRootServer < UPnP::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
super
|
10
|
+
|
11
|
+
@device = UPnP::Device.new 'TestDevice', 'test device'
|
12
|
+
@device.manufacturer = 'UPnP Manufacturer'
|
13
|
+
@device.model_name = 'UPnP Model'
|
14
|
+
|
15
|
+
@service = @device.add_service 'TestService'
|
16
|
+
|
17
|
+
@root_server = UPnP::RootServer.new @device
|
18
|
+
|
19
|
+
@req = WEBrick::HTTPRequest.new :Logger => nil
|
20
|
+
@res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_initialize
|
24
|
+
assert_equal @device, @root_server.root_device
|
25
|
+
assert @root_server.scpds.empty?
|
26
|
+
assert_equal WEBrick::BasicLog::FATAL, @root_server.logger.level,
|
27
|
+
'default log level'
|
28
|
+
|
29
|
+
assert util_mount_tab['/description']
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_description
|
33
|
+
data = StringIO.new "GET /description HTTP/1.0\r\n\r\n"
|
34
|
+
@req.parse data
|
35
|
+
|
36
|
+
@root_server.description @req, @res
|
37
|
+
|
38
|
+
assert_equal 200, @res.status, @res.body
|
39
|
+
assert_equal 'text/xml', @res['content-type']
|
40
|
+
assert_equal @device.description, @res.body
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_description_other
|
44
|
+
data = StringIO.new "GET /description/other HTTP/1.0\r\n\r\n"
|
45
|
+
@req.parse data
|
46
|
+
|
47
|
+
assert_raise WEBrick::HTTPStatus::NotFound do
|
48
|
+
@root_server.description @req, @res
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_mount_server
|
53
|
+
assert_nil util_mount_tab['/TestDevice/TestService/control']
|
54
|
+
|
55
|
+
@root_server.mount_server @service.control_url, @service.server
|
56
|
+
|
57
|
+
assert_equal @root_server.logger, @service.server.config[:Logger]
|
58
|
+
assert util_mount_tab['/TestDevice/TestService/control']
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_mount_service
|
62
|
+
@root_server.mount_service @service
|
63
|
+
|
64
|
+
assert_equal [@service.scpd_url], @root_server.scpds.keys
|
65
|
+
|
66
|
+
assert util_mount_tab['/TestDevice/TestService']
|
67
|
+
assert util_mount_tab['/TestDevice/TestService/control']
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_scpd
|
71
|
+
@root_server.mount_service @service
|
72
|
+
|
73
|
+
data = StringIO.new "GET #{@service.scpd_url} HTTP/1.0\r\n\r\n"
|
74
|
+
@req.parse data
|
75
|
+
|
76
|
+
@root_server.scpd @req, @res
|
77
|
+
|
78
|
+
assert_equal 200, @res.status, @res.body
|
79
|
+
assert_equal 'text/xml', @res['content-type']
|
80
|
+
assert_equal @service.scpd, @res.body
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_scpd_other
|
84
|
+
@root_server.mount_service @service
|
85
|
+
|
86
|
+
data = StringIO.new "GET /TestDevice/TestOtherService HTTP/1.0\r\n\r\n"
|
87
|
+
@req.parse data
|
88
|
+
|
89
|
+
assert_raise WEBrick::HTTPStatus::NotFound do
|
90
|
+
@root_server.description @req, @res
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def util_mount_tab
|
95
|
+
@root_server.instance_variable_get :@mount_tab
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'test/utilities'
|
3
|
+
require 'UPnP/service'
|
4
|
+
|
5
|
+
class TestUPnPService < UPnP::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
super
|
9
|
+
|
10
|
+
@device = UPnP::Device.new 'TestDevice', 'test device'
|
11
|
+
@service = @device.add_service 'TestService'
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_initialize
|
15
|
+
assert_equal @device, @service.device
|
16
|
+
assert_equal 'TestService', @service.type
|
17
|
+
|
18
|
+
assert_equal 'TestService', @service.appname
|
19
|
+
assert_equal "#{UPnP::SERVICE_SCHEMA_PREFIX}:TestService:1",
|
20
|
+
@service.default_namespace
|
21
|
+
|
22
|
+
router = @service.instance_variable_get :@router
|
23
|
+
operations = router.instance_variable_get :@operation_by_qname
|
24
|
+
|
25
|
+
qname = XSD::QName.new @service.type_urn, 'TestAction'
|
26
|
+
|
27
|
+
assert operations.key?(qname)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_actions
|
31
|
+
expected = {
|
32
|
+
'TestAction' => [
|
33
|
+
%w[in TestInput TestInVar],
|
34
|
+
%w[out TestOutput TestOutVar],
|
35
|
+
],
|
36
|
+
}
|
37
|
+
|
38
|
+
assert_equal expected, @service.actions
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_add_actions
|
42
|
+
router = @service.instance_variable_get :@router
|
43
|
+
operations = router.instance_variable_get :@operation_by_qname
|
44
|
+
|
45
|
+
qname = XSD::QName.new @service.type_urn, 'TestAction'
|
46
|
+
|
47
|
+
assert_equal [qname], operations.keys
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_control_url
|
51
|
+
assert_equal '/TestDevice/TestService/control', @service.control_url
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_create_config
|
55
|
+
assert_equal true, @service.create_config[:DoNotListen]
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_description
|
59
|
+
desc = ''
|
60
|
+
xml = Builder::XmlMarkup.new :indent => 2, :target => desc
|
61
|
+
|
62
|
+
@service.description xml
|
63
|
+
|
64
|
+
expected = <<-XML
|
65
|
+
<service>
|
66
|
+
<serviceType>urn:schemas-upnp-org:service:TestService:1</serviceType>
|
67
|
+
<serviceId>urn:upnp-org:serviceId:TestService</serviceId>
|
68
|
+
<SCPDURL>/TestDevice/TestService</SCPDURL>
|
69
|
+
<controlURL>/TestDevice/TestService/control</controlURL>
|
70
|
+
<eventSubURL>/TestDevice/TestService/event_sub</eventSubURL>
|
71
|
+
</service>
|
72
|
+
XML
|
73
|
+
|
74
|
+
assert_equal expected, desc
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_device_path
|
78
|
+
assert_equal '/TestDevice', @service.device_path
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_event_sub_url
|
82
|
+
assert_equal '/TestDevice/TestService/event_sub', @service.event_sub_url
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_marshal_dump
|
86
|
+
assert_equal [@device, 'TestService'], @service.marshal_dump
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_marshal_load
|
90
|
+
data = [@device, 'TestService']
|
91
|
+
|
92
|
+
service = UPnP::Service.allocate
|
93
|
+
|
94
|
+
service.marshal_load data
|
95
|
+
|
96
|
+
assert_equal 'TestService', @service.type
|
97
|
+
assert_equal 'TestService', @service.appname
|
98
|
+
|
99
|
+
assert data.empty?, 'unconsumed data'
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_root_device
|
103
|
+
assert_equal @device, @service.root_device
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_scpd
|
107
|
+
scpd = @service.scpd
|
108
|
+
|
109
|
+
expected = <<-XML
|
110
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
111
|
+
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
|
112
|
+
<specVersion>
|
113
|
+
<major>1</major>
|
114
|
+
<minor>0</minor>
|
115
|
+
</specVersion>
|
116
|
+
<actionList>
|
117
|
+
<action>
|
118
|
+
<name>TestAction</name>
|
119
|
+
<argumentList>
|
120
|
+
<argument>
|
121
|
+
<direction>in</direction>
|
122
|
+
<name>TestInput</name>
|
123
|
+
<relatedStateVariable>TestInVar</relatedStateVariable>
|
124
|
+
</argument>
|
125
|
+
<argument>
|
126
|
+
<direction>out</direction>
|
127
|
+
<name>TestOutput</name>
|
128
|
+
<relatedStateVariable>TestOutVar</relatedStateVariable>
|
129
|
+
</argument>
|
130
|
+
</argumentList>
|
131
|
+
</action>
|
132
|
+
</actionList>
|
133
|
+
<serviceStateTable>
|
134
|
+
<stateVariable sendEvents="no">
|
135
|
+
<name>TestOutVar</name>
|
136
|
+
<dataType>string</dataType>
|
137
|
+
</stateVariable>
|
138
|
+
<stateVariable sendEvents="no">
|
139
|
+
<name>TestInVar</name>
|
140
|
+
<dataType>string</dataType>
|
141
|
+
</stateVariable>
|
142
|
+
</serviceStateTable>
|
143
|
+
</scpd>
|
144
|
+
XML
|
145
|
+
|
146
|
+
assert_equal expected, scpd
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_scpd_url
|
150
|
+
assert_equal '/TestDevice/TestService', @service.scpd_url
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_service_path
|
154
|
+
assert_equal '/TestDevice/TestService', @service.service_path
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_type_urn
|
158
|
+
assert_equal 'urn:schemas-upnp-org:service:TestService:1', @service.type_urn
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_variables
|
162
|
+
expected = {
|
163
|
+
'TestOutVar' => ['string', nil, nil, false],
|
164
|
+
'TestInVar' => ['string', nil, nil, false],
|
165
|
+
}
|
166
|
+
|
167
|
+
assert_equal expected, @service.variables
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
data/test/utilities.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'tmpdir'
|
1
3
|
require 'test/unit'
|
4
|
+
require 'UPnP'
|
5
|
+
require 'UPnP/device'
|
2
6
|
|
3
7
|
module UPnP
|
4
8
|
|
@@ -67,23 +71,30 @@ module UPnP
|
|
67
71
|
|
68
72
|
class TestCase < Test::Unit::TestCase
|
69
73
|
|
74
|
+
undef_method :default_test
|
75
|
+
|
76
|
+
def setup
|
77
|
+
@tempdir = File.join Dir.tmpdir, "test_UPnP_#{$$}"
|
78
|
+
FileUtils.mkdir_p @tempdir
|
79
|
+
|
80
|
+
@home = File.join @tempdir, 'home'
|
81
|
+
FileUtils.mkdir_p @home
|
82
|
+
|
83
|
+
@orig_ENV_HOME = ENV['HOME']
|
84
|
+
ENV['HOME'] = @home
|
85
|
+
end
|
86
|
+
|
70
87
|
def teardown
|
88
|
+
if @orig_ENV_HOME then
|
89
|
+
ENV['HOME'] = @orig_ENV_HOME
|
90
|
+
else
|
91
|
+
ENV.delete 'HOME'
|
92
|
+
end
|
93
|
+
|
94
|
+
FileUtils.rm_rf @tempdir
|
71
95
|
UPnP::OpenStub::FILES.clear
|
72
96
|
end
|
73
97
|
|
74
|
-
def util_search_response
|
75
|
-
<<-SEARCH_RESPONSE
|
76
|
-
HTTP/1.1 200 OK\r
|
77
|
-
CACHE-CONTROL: max-age = 10\r
|
78
|
-
EXT:\r
|
79
|
-
LOCATION: http://example.com/root_device.xml\r
|
80
|
-
SERVER: OS/5 UPnP/1.0 product/7\r
|
81
|
-
ST: upnp:rootdevice\r
|
82
|
-
USN: uuid:BOGUS::upnp:rootdevice\r
|
83
|
-
\r
|
84
|
-
SEARCH_RESPONSE
|
85
|
-
end
|
86
|
-
|
87
98
|
def util_notify
|
88
99
|
<<-NOTIFY
|
89
100
|
NOTIFY * HTTP/1.1\r
|
@@ -109,7 +120,28 @@ USN: uuid:BOGUS::upnp:rootdevice\r
|
|
109
120
|
NOTIFY_BYEBYE
|
110
121
|
end
|
111
122
|
|
112
|
-
|
123
|
+
def util_search
|
124
|
+
<<-SEARCH
|
125
|
+
M-SEARCH * HTTP/1.1
|
126
|
+
HOST: 239.255.255.250:1900
|
127
|
+
MAN: "ssdp:discover"
|
128
|
+
MX: 2
|
129
|
+
ST: upnp:rootdevice
|
130
|
+
SEARCH
|
131
|
+
end
|
132
|
+
|
133
|
+
def util_search_response
|
134
|
+
<<-SEARCH_RESPONSE
|
135
|
+
HTTP/1.1 200 OK\r
|
136
|
+
CACHE-CONTROL: max-age = 10\r
|
137
|
+
EXT:\r
|
138
|
+
LOCATION: http://example.com/root_device.xml\r
|
139
|
+
SERVER: OS/5 UPnP/1.0 product/7\r
|
140
|
+
ST: upnp:rootdevice\r
|
141
|
+
USN: uuid:BOGUS::upnp:rootdevice\r
|
142
|
+
\r
|
143
|
+
SEARCH_RESPONSE
|
144
|
+
end
|
113
145
|
|
114
146
|
IGD_XML = <<-XML
|
115
147
|
<?xml version="1.0"?>
|
@@ -1024,5 +1056,20 @@ USN: uuid:BOGUS::upnp:rootdevice\r
|
|
1024
1056
|
|
1025
1057
|
end
|
1026
1058
|
|
1059
|
+
class Service::TestService < Service
|
1060
|
+
add_action 'TestAction',
|
1061
|
+
[IN, 'TestInput', 'TestInVar'],
|
1062
|
+
[OUT, 'TestOutput', 'TestOutVar']
|
1063
|
+
|
1064
|
+
add_variable 'TestInVar', 'string'
|
1065
|
+
add_variable 'TestOutVar', 'string'
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
class Device::TestDevice < Device
|
1069
|
+
|
1070
|
+
add_service_id UPnP::Service::TestService, 'TestService'
|
1071
|
+
|
1072
|
+
end
|
1073
|
+
|
1027
1074
|
end
|
1028
1075
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: UPnP
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Hodel
|
@@ -30,18 +30,38 @@ cert_chain:
|
|
30
30
|
x52qPcexcYZR7w==
|
31
31
|
-----END CERTIFICATE-----
|
32
32
|
|
33
|
-
date: 2008-
|
33
|
+
date: 2008-07-23 00:00:00 -07:00
|
34
34
|
default_executable:
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
37
|
+
name: soap4r
|
38
|
+
type: :runtime
|
39
|
+
version_requirement:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: builder
|
38
48
|
type: :runtime
|
39
49
|
version_requirement:
|
40
50
|
version_requirements: !ruby/object:Gem::Requirement
|
41
51
|
requirements:
|
42
52
|
- - ">="
|
43
53
|
- !ruby/object:Gem::Version
|
44
|
-
version:
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: hoe
|
58
|
+
type: :development
|
59
|
+
version_requirement:
|
60
|
+
version_requirements: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 1.7.0
|
45
65
|
version:
|
46
66
|
description: An implementation of the UPnP protocol
|
47
67
|
email:
|
@@ -65,14 +85,22 @@ files:
|
|
65
85
|
- bin/upnp_listen
|
66
86
|
- lib/UPnP.rb
|
67
87
|
- lib/UPnP/SSDP.rb
|
88
|
+
- lib/UPnP/UUID.rb
|
68
89
|
- lib/UPnP/control.rb
|
69
90
|
- lib/UPnP/control/device.rb
|
70
91
|
- lib/UPnP/control/service.rb
|
92
|
+
- lib/UPnP/device.rb
|
93
|
+
- lib/UPnP/root_server.rb
|
94
|
+
- lib/UPnP/service.rb
|
71
95
|
- test/test_UPnP_SSDP.rb
|
72
96
|
- test/test_UPnP_SSDP_notification.rb
|
73
97
|
- test/test_UPnP_SSDP_response.rb
|
98
|
+
- test/test_UPnP_SSDP_search.rb
|
74
99
|
- test/test_UPnP_control_device.rb
|
75
100
|
- test/test_UPnP_control_service.rb
|
101
|
+
- test/test_UPnP_device.rb
|
102
|
+
- test/test_UPnP_root_server.rb
|
103
|
+
- test/test_UPnP_service.rb
|
76
104
|
- test/utilities.rb
|
77
105
|
has_rdoc: true
|
78
106
|
homepage: http://seattlerb.org/UPnP
|
@@ -104,6 +132,10 @@ summary: An implementation of the UPnP protocol
|
|
104
132
|
test_files:
|
105
133
|
- test/test_UPnP_control_device.rb
|
106
134
|
- test/test_UPnP_control_service.rb
|
135
|
+
- test/test_UPnP_device.rb
|
136
|
+
- test/test_UPnP_root_server.rb
|
137
|
+
- test/test_UPnP_service.rb
|
107
138
|
- test/test_UPnP_SSDP.rb
|
108
139
|
- test/test_UPnP_SSDP_notification.rb
|
109
140
|
- test/test_UPnP_SSDP_response.rb
|
141
|
+
- test/test_UPnP_SSDP_search.rb
|