UPnP 1.0.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.
@@ -0,0 +1,237 @@
1
+ require 'test/unit'
2
+ require 'test/utilities'
3
+ require 'UPnP/SSDP'
4
+
5
+ class TestUPnPSSDP < UPnP::TestCase
6
+
7
+ def setup
8
+ @ssdp = UPnP::SSDP.new
9
+ @ssdp.timeout = 0
10
+ end
11
+
12
+ def teardown
13
+ @ssdp.listener.kill if @ssdp.listener
14
+ end
15
+
16
+ def test_discover
17
+ socket = UPnP::FakeSocket.new util_notify
18
+ @ssdp.socket = socket
19
+
20
+ notifications = @ssdp.discover
21
+
22
+ assert_equal [], socket.sent
23
+ assert_equal [Socket::INADDR_ANY, @ssdp.port], socket.bound
24
+
25
+ expected = [
26
+ [Socket::IPPROTO_IP, Socket::IP_TTL, [@ssdp.ttl].pack('i')],
27
+ [Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP,
28
+ "\357\377\377\372\000\000\000\000"]
29
+ ]
30
+
31
+ assert_equal expected, socket.socket_options
32
+
33
+ assert_equal 1, notifications.length
34
+ assert_equal 'upnp:rootdevice', notifications.first.type
35
+ end
36
+
37
+ def test_listen
38
+ @ssdp.socket = UPnP::FakeSocket.new util_notify
39
+
40
+ @ssdp.listen
41
+
42
+ notification = @ssdp.queue.pop
43
+
44
+ assert_equal 'upnp:rootdevice', notification.type
45
+ end
46
+
47
+ def test_parse_bad
48
+ assert_raise UPnP::SSDP::Error do
49
+ @ssdp.parse ''
50
+ end
51
+ end
52
+
53
+ def test_parse_notification
54
+ notification = @ssdp.parse util_notify
55
+
56
+ assert_equal 'upnp:rootdevice', notification.type
57
+ end
58
+
59
+ def test_parse_notification_byebye
60
+ notification = @ssdp.parse util_notify
61
+
62
+ assert_equal 'upnp:rootdevice', notification.type
63
+ end
64
+
65
+ def test_parse_search_response
66
+ response = @ssdp.parse util_search_response
67
+
68
+ assert_equal 'upnp:rootdevice', response.target
69
+ end
70
+
71
+ def test_search
72
+ socket = UPnP::FakeSocket.new util_search_response
73
+ @ssdp.socket = socket
74
+
75
+ responses = @ssdp.search
76
+
77
+ assert_equal nil, socket.bound
78
+
79
+ m_search = <<-M_SEARCH
80
+ M-SEARCH * HTTP/1.1\r
81
+ HOST: 239.255.255.250:1900\r
82
+ MAN: \"ssdp:discover\"\r
83
+ MX: 0\r
84
+ ST: ssdp:all\r
85
+ \r
86
+ M_SEARCH
87
+
88
+ assert_equal [[m_search, 0, @ssdp.broadcast, @ssdp.port]], socket.sent
89
+
90
+ expected = [
91
+ [Socket::IPPROTO_IP, Socket::IP_TTL, [@ssdp.ttl].pack('i')],
92
+ ]
93
+
94
+ assert_equal expected, socket.socket_options
95
+
96
+ assert_equal 1, responses.length
97
+ assert_equal 'upnp:rootdevice', responses.first.target
98
+ end
99
+
100
+ def test_search_device
101
+ socket = UPnP::FakeSocket.new util_search_response
102
+ @ssdp.socket = socket
103
+
104
+ responses = @ssdp.search [:device, 'MyDevice.1']
105
+
106
+ m_search = <<-M_SEARCH
107
+ M-SEARCH * HTTP/1.1\r
108
+ HOST: 239.255.255.250:1900\r
109
+ MAN: \"ssdp:discover\"\r
110
+ MX: 0\r
111
+ ST: urn:schemas-upnp-org:device:MyDevice.1\r
112
+ \r
113
+ M_SEARCH
114
+
115
+ assert_equal [[m_search, 0, @ssdp.broadcast, @ssdp.port]], socket.sent
116
+ end
117
+
118
+ def test_search_root
119
+ socket = UPnP::FakeSocket.new util_search_response
120
+ @ssdp.socket = socket
121
+
122
+ responses = @ssdp.search :root
123
+
124
+ m_search = <<-M_SEARCH
125
+ M-SEARCH * HTTP/1.1\r
126
+ HOST: 239.255.255.250:1900\r
127
+ MAN: \"ssdp:discover\"\r
128
+ MX: 0\r
129
+ ST: upnp:rootdevice\r
130
+ \r
131
+ M_SEARCH
132
+
133
+ assert_equal [[m_search, 0, @ssdp.broadcast, @ssdp.port]], socket.sent
134
+ end
135
+
136
+ def test_search_service
137
+ socket = UPnP::FakeSocket.new util_search_response
138
+ @ssdp.socket = socket
139
+
140
+ responses = @ssdp.search [:service, 'MyService.1']
141
+
142
+ m_search = <<-M_SEARCH
143
+ M-SEARCH * HTTP/1.1\r
144
+ HOST: 239.255.255.250:1900\r
145
+ MAN: \"ssdp:discover\"\r
146
+ MX: 0\r
147
+ ST: urn:schemas-upnp-org:service:MyService.1\r
148
+ \r
149
+ M_SEARCH
150
+
151
+ assert_equal [[m_search, 0, @ssdp.broadcast, @ssdp.port]], socket.sent
152
+ end
153
+
154
+ def test_search_ssdp
155
+ socket = UPnP::FakeSocket.new util_search_response
156
+ @ssdp.socket = socket
157
+
158
+ responses = @ssdp.search 'ssdp:foo'
159
+
160
+ m_search = <<-M_SEARCH
161
+ M-SEARCH * HTTP/1.1\r
162
+ HOST: 239.255.255.250:1900\r
163
+ MAN: \"ssdp:discover\"\r
164
+ MX: 0\r
165
+ ST: ssdp:foo\r
166
+ \r
167
+ M_SEARCH
168
+
169
+ assert_equal [[m_search, 0, @ssdp.broadcast, @ssdp.port]], socket.sent
170
+ end
171
+
172
+ def test_search_urn
173
+ socket = UPnP::FakeSocket.new util_search_response
174
+ @ssdp.socket = socket
175
+
176
+ responses = @ssdp.search 'urn:foo'
177
+
178
+ m_search = <<-M_SEARCH
179
+ M-SEARCH * HTTP/1.1\r
180
+ HOST: 239.255.255.250:1900\r
181
+ MAN: \"ssdp:discover\"\r
182
+ MX: 0\r
183
+ ST: urn:foo\r
184
+ \r
185
+ M_SEARCH
186
+
187
+ assert_equal [[m_search, 0, @ssdp.broadcast, @ssdp.port]], socket.sent
188
+ end
189
+
190
+ def test_search_uuid
191
+ socket = UPnP::FakeSocket.new util_search_response
192
+ @ssdp.socket = socket
193
+
194
+ responses = @ssdp.search 'uuid:foo'
195
+
196
+ m_search = <<-M_SEARCH
197
+ M-SEARCH * HTTP/1.1\r
198
+ HOST: 239.255.255.250:1900\r
199
+ MAN: \"ssdp:discover\"\r
200
+ MX: 0\r
201
+ ST: uuid:foo\r
202
+ \r
203
+ M_SEARCH
204
+
205
+ assert_equal [[m_search, 0, @ssdp.broadcast, @ssdp.port]], socket.sent
206
+ end
207
+
208
+ def test_send_search
209
+ socket = UPnP::FakeSocket.new
210
+ @ssdp.socket = socket
211
+
212
+ @ssdp.send_search 'bunnies'
213
+
214
+ search = <<-SEARCH
215
+ M-SEARCH * HTTP/1.1\r
216
+ HOST: 239.255.255.250:1900\r
217
+ MAN: \"ssdp:discover\"\r
218
+ MX: 0\r
219
+ ST: bunnies\r
220
+ \r
221
+ SEARCH
222
+
223
+ assert_equal [[search, 0, @ssdp.broadcast, @ssdp.port]], socket.sent
224
+ end
225
+
226
+ def test_stop_listening
227
+ thread = Thread.new do sleep end
228
+ @ssdp.listener = thread
229
+
230
+ @ssdp.stop_listening
231
+
232
+ assert_equal false, thread.alive?
233
+ assert_equal nil, @ssdp.listener
234
+ end
235
+
236
+ end
237
+
@@ -0,0 +1,74 @@
1
+ require 'test/unit'
2
+ require 'test/utilities'
3
+ require 'UPnP/SSDP'
4
+
5
+ class TestUPnPSSDPNotification < UPnP::TestCase
6
+
7
+ def test_self_parse_notify
8
+ notification = UPnP::SSDP::Notification.parse util_notify
9
+
10
+ assert_equal Time, notification.date.class
11
+ assert_equal '239.255.255.250', notification.host
12
+ assert_equal '1900', notification.port
13
+ assert_equal URI.parse('http://example.com/root_device.xml'),
14
+ notification.location
15
+ assert_equal 10, notification.max_age
16
+ assert_equal 'uuid:BOGUS::upnp:rootdevice', notification.name
17
+ assert_equal 'upnp:rootdevice', notification.type
18
+ assert_equal 'OS/5 UPnP/1.0 product/7', notification.server
19
+ assert_equal 'ssdp:alive', notification.sub_type
20
+ end
21
+
22
+ def test_self_parse_notify_byebye
23
+ notification = UPnP::SSDP::Notification.parse util_notify_byebye
24
+
25
+ assert_equal Time, notification.date.class
26
+ assert_equal '239.255.255.250', notification.host
27
+ assert_equal '1900', notification.port
28
+ assert_equal nil, notification.location
29
+ assert_equal nil, notification.max_age
30
+ assert_equal 'uuid:BOGUS::upnp:rootdevice', notification.name
31
+ assert_equal 'upnp:rootdevice', notification.type
32
+ assert_equal 'ssdp:byebye', notification.sub_type
33
+ end
34
+
35
+ def test_alive_eh
36
+ notification = UPnP::SSDP::Notification.parse util_notify
37
+
38
+ assert notification.alive?
39
+
40
+ notification = UPnP::SSDP::Notification.parse util_notify_byebye
41
+
42
+ assert !notification.alive?
43
+ end
44
+
45
+ def test_byebye_eh
46
+ notification = UPnP::SSDP::Notification.parse util_notify_byebye
47
+
48
+ assert notification.byebye?
49
+
50
+ notification = UPnP::SSDP::Notification.parse util_notify
51
+
52
+ assert !notification.byebye?
53
+ end
54
+
55
+ def test_inspect
56
+ notification = UPnP::SSDP::Notification.parse util_notify
57
+
58
+ id = notification.object_id.to_s 16
59
+ expected = "#<UPnP::SSDP::Notification:0x#{id} upnp:rootdevice ssdp:alive http://example.com/root_device.xml>"
60
+
61
+ assert_equal expected, notification.inspect
62
+ end
63
+
64
+ def test_inspect_byebye
65
+ notification = UPnP::SSDP::Notification.parse util_notify_byebye
66
+
67
+ id = notification.object_id.to_s 16
68
+ expected = "#<UPnP::SSDP::Notification:0x#{id} upnp:rootdevice ssdp:byebye>"
69
+
70
+ assert_equal expected, notification.inspect
71
+ end
72
+
73
+ end
74
+
@@ -0,0 +1,30 @@
1
+ require 'test/unit'
2
+ require 'test/utilities'
3
+ require 'UPnP/SSDP'
4
+
5
+ class TestUPnPSSDPResponse < UPnP::TestCase
6
+
7
+ def setup
8
+ @response = UPnP::SSDP::Response.parse util_search_response
9
+ end
10
+
11
+ def test_self_parse_notify
12
+ assert_equal Time, @response.date.class
13
+ assert_equal true, @response.ext
14
+ assert_equal URI.parse('http://example.com/root_device.xml'),
15
+ @response.location
16
+ assert_equal 10, @response.max_age
17
+ assert_equal 'uuid:BOGUS::upnp:rootdevice', @response.name
18
+ assert_equal 'OS/5 UPnP/1.0 product/7', @response.server
19
+ assert_equal 'upnp:rootdevice', @response.target
20
+ end
21
+
22
+ def test_inspect
23
+ id = @response.object_id.to_s 16
24
+ expected = "#<UPnP::SSDP::Response:0x#{id} upnp:rootdevice http://example.com/root_device.xml>"
25
+
26
+ assert_equal expected, @response.inspect
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,72 @@
1
+ require 'test/unit'
2
+ require 'stringio'
3
+ require 'test/utilities'
4
+ require 'UPnP/control/device'
5
+
6
+ class TestUPnPControlDevice < UPnP::TestCase
7
+
8
+ def setup
9
+ @device_url = URI.parse 'http://example.com/device.xml'
10
+
11
+ UPnP::OpenStub::FILES[@device_url] = StringIO.new UPnP::TestCase::IGD_XML
12
+ UPnP::OpenStub::FILES[@device_url + '/L3F.xml'] =
13
+ StringIO.new UPnP::TestCase::L3F_XML
14
+ UPnP::OpenStub::FILES[@device_url + '/WANCfg.xml'] =
15
+ StringIO.new UPnP::TestCase::CFG_XML
16
+ UPnP::OpenStub::FILES[@device_url + '/WANIPCn.xml'] =
17
+ StringIO.new UPnP::TestCase::IPCN_XML
18
+ end
19
+
20
+ def test_self_create
21
+ device = UPnP::Control::Device.create @device_url
22
+
23
+ igd = UPnP::Control::Device::InternetGatewayDevice
24
+
25
+ assert_equal igd, device.class
26
+ assert igd.constants.include?('URN_1'), 'URN_1 constant missing'
27
+ assert_equal "#{UPnP::DEVICE_SCHEMA_PREFIX}:#{igd.name}:1", igd::URN_1
28
+ ensure
29
+ UPnP::Control::Device.send :remove_const, :InternetGatewayDevice
30
+ end
31
+
32
+ def test_self_create_class_exists
33
+ UPnP::Control::Device.const_set :InternetGatewayDevice,
34
+ Class.new(UPnP::Control::Device)
35
+
36
+ device = UPnP::Control::Device.create @device_url
37
+
38
+ assert_equal UPnP::Control::Device::InternetGatewayDevice, device.class
39
+ ensure
40
+ UPnP::Control::Device.send :remove_const, :InternetGatewayDevice
41
+ end
42
+
43
+ def test_initialize
44
+ device = UPnP::Control::Device.new @device_url
45
+
46
+ assert_equal 'http://example.com/', device.url.to_s
47
+ assert_equal 'urn:schemas-upnp-org:device:InternetGatewayDevice:1',
48
+ device.type
49
+
50
+ assert_equal 'FreeBSD router', device.friendly_name
51
+
52
+ assert_equal 'FreeBSD', device.manufacturer
53
+ assert_equal URI.parse('http://www.freebsd.org/'), device.manufacturer_url
54
+
55
+ assert_equal 'FreeBSD router', device.model_description
56
+ assert_equal 'FreeBSD router', device.model_name
57
+ assert_equal URI.parse('http://www.freebsd.org/'), device.model_url
58
+ assert_equal '1', device.model_number
59
+
60
+ assert_equal '00000000', device.serial_number
61
+
62
+ assert_equal 'uuid:ed56cff8-7d4e-11dc-b7db-000024c4931c', device.name
63
+
64
+ assert_equal 2, device.devices.length, 'devices count'
65
+ assert_equal 1, device.sub_devices.length, 'sub-devices count'
66
+
67
+ assert_equal 3, device.services.length, 'services count'
68
+ assert_equal 1, device.sub_services.length, 'sub-services count'
69
+ end
70
+
71
+ end
72
+
@@ -0,0 +1,108 @@
1
+ require 'test/unit'
2
+ require 'test/utilities'
3
+ require 'UPnP/control/service'
4
+
5
+ class TestUPnPControlService < UPnP::TestCase
6
+
7
+ def setup
8
+ @url = URI.parse 'http://example.com'
9
+ service_description = <<-XML
10
+ <service>
11
+ <serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType>
12
+ <serviceId>urn:upnp-org:serviceId:Layer3Forwarding1</serviceId>
13
+ <controlURL>/ctl/L3F</controlURL>
14
+ <eventSubURL>/evt/L3F</eventSubURL>
15
+ <SCPDURL>/L3F.xml</SCPDURL>
16
+ </service>
17
+ XML
18
+
19
+ service_description = REXML::Document.new service_description
20
+ @service_description = service_description.elements['service']
21
+
22
+ UPnP::Control::Service::FILES[@url + '/L3F.xml'] = StringIO.new L3F_XML
23
+
24
+ @methods = %w[
25
+ AddPortMapping
26
+ DeletePortMapping
27
+ ForceTermination
28
+ GetConnectionTypeInfo
29
+ GetExternalIPAddress
30
+ GetGenericPortMappingEntry
31
+ GetNATRSIPStatus
32
+ GetSpecificPortMappingEntry
33
+ GetStatusInfo
34
+ RequestConnection
35
+ SetConnectionType
36
+ ]
37
+ end
38
+
39
+ def test_self_create
40
+ device = UPnP::Control::Service.create @service_description, @url
41
+
42
+ l3f = UPnP::Control::Service::Layer3Forwarding
43
+ assert_equal l3f, device.class
44
+
45
+ assert l3f.constants.include?('URN_1'), 'URN_1 constant missing'
46
+ assert_equal "#{UPnP::SERVICE_SCHEMA_PREFIX}:#{l3f.name}:1", l3f::URN_1
47
+ ensure
48
+ UPnP::Control::Service.send :remove_const, :Layer3Forwarding
49
+ end
50
+
51
+ def test_self_create_class_exists
52
+ UPnP::Control::Service.const_set :Layer3Forwarding,
53
+ Class.new(UPnP::Control::Service)
54
+
55
+ device = UPnP::Control::Service.create @service_description, @url
56
+
57
+ assert_equal UPnP::Control::Service::Layer3Forwarding, device.class
58
+ ensure
59
+ UPnP::Control::Service.send :remove_const, :Layer3Forwarding
60
+ end
61
+
62
+ def test_initialize
63
+ service = UPnP::Control::Service.new @service_description, @url
64
+
65
+ assert_equal @url, service.url
66
+
67
+ assert_equal 'urn:schemas-upnp-org:service:Layer3Forwarding:1',
68
+ service.type
69
+
70
+ assert_equal 'urn:upnp-org:serviceId:Layer3Forwarding1', service.id
71
+
72
+ control_url = @url + '/ctl/L3F'
73
+ assert_equal control_url, service.control_url
74
+
75
+ evt_url = @url + '/evt/L3F'
76
+ assert_equal evt_url, service.event_sub_url
77
+
78
+ scpd_url = @url + '/L3F.xml'
79
+ assert_equal scpd_url, service.scpd_url
80
+
81
+ assert_not_nil service.driver
82
+ end
83
+
84
+ def test_create_driver
85
+ service = UPnP::Control::Service.create @service_description, @url
86
+
87
+ assert_equal @methods, service.driver.methods(false).sort
88
+
89
+ registry = service.driver.mapping_registry
90
+
91
+ klass_def = registry.elename_schema_definition_from_class SOAP::SOAPString
92
+ assert_equal 'NewPossibleConnectionTypes', klass_def.elename.name
93
+
94
+ new_protocol = XSD::QName.new nil, 'NewProtocol'
95
+ mapping = registry.schema_definition_from_elename new_protocol
96
+ assert mapping, "Mapping for #{new_protocol} not found"
97
+
98
+ assert service.respond_to?(@methods.first)
99
+ end
100
+
101
+ def test_methods
102
+ service = UPnP::Control::Service.new @service_description, @url
103
+
104
+ assert_equal @methods, service.methods(false).sort
105
+ end
106
+
107
+ end
108
+