初老のボケ防止日記

おっさんのひとりごとだから気にしないようにな。

DLNAってなんじゃらほい? - SSDPを喋ってみる -

前回、DLNAがNW上の各機器の発見をするのにUPnPを使っていて、UPnPはSSDPを用いてデバイスの発見をしていることがわかった。でもって、SSDPはマルチキャストUDPでHTTPUを喋ればよいというところまでわかったので実際に試してみることにした。

UPnP的にはNotifyとかもあるらしいけど、今回はとりあえずSearchできればいいやと。でも、どうやってSSDPのSearchするのよと調べてみた。



SSDPでSearchはどうやるのか

Simple Service Discovery Protocol - Wikipedia

SSDP uses a NOTIFY HTTP method to announce the establishment or withdrawal of services (presence) information to the multicast group. A client that wishes to discover available services on a network, uses the M-SEARCH method. Responses to such search requests are sent via unicast addressing to the originating address and port number of the multicast request.

M-SEARCHメソッド使えばいいいのね。Sの人を探す場合はS-SEARCHなんだろうか、あ嘘ですマルチキャストのMですよねー。はい、じゃあ肝心のHTTPUのリクエストフォーマットは?


M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: seconds to delay response
ST: search target
USER-AGENT: OS/version UPnP/1.1 product/version

お、簡単そうじゃないか。一応、公式仕様書を見てみます。

OPEN CONNECTIVITY FOUNDATION (OCF)

最新バージョンは2.0なんだけどちょっと最新すぎるのでここは1.0を見てみましょう。

http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.0.pdf

M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: seconds to delay response
ST: search target

USER-AGENTがないだけで一緒。MXはタイムアウトだろうけど、STに何を指定すればいいのか仕様書読んでもよくわからん。

Search Target. Must be one of the following. (cf. NT header in NOTIFY with ssdp:alive above.) Single URI.

でも色々とぐぐると"upnp:rootdevice"を指定してる例が多いのでそれでやっちゃおう。

M-SEARCHしてみる

ということで、pythonでM-SEARCHを投げるコードを書く。適当だけど気にしない。動くのが一番大事マンブラザーズバンド。

import socket

MSEARCH_REQUEST_LINES = (
'M-SEARCH * HTTP/1.1',
'HOST: 239.255.255.250:1900',
'MAN: "ssdp:discover"',
'MX: %(timeout)s',
'ST:upnp:rootdevice',
'',
''
)

timeout = 5
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(timeout)
req = '\r\n'.join(MSEARCH_REQUEST_LINES) % {'timeout': timeout}
sock.sendto(req, ('239.255.255.250', 1900))
while True:
    try:
        res, device = sock.recvfrom(4096)
        print '----------- from %s' % (device,)
        print res
        print '-----------'
    except socket.timeout:
        break

sock.close()

我が家のDLNA機器*1

実験した時に稼働していたのはこんな感じ

機器 機種 ソフト 備考
NAS QNAP Twonky Server 音楽格納してる
AP WZR-1750DHP2 非公開*2 実験で有効化
PC VAIO - M-SEARCH実行用
Android SH-06E BubbleUPnP QNAPの音楽をコレでいつも聴いてる
NWスピーカー CMT-X7CD - たまにこれで音を出している

実行してみた。

実際はルータやChromecast*3も応答してきたんだけど、DLNAと関係ないので除外。

# QNAP
----------- from ('xxx.xxx.x.250', 33104)
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=1810
DATE: Tue, 06 Jan 2015 14:28:56 GMT
EXT:
LOCATION: http://xxx.xxx.x.250:9000/TMSDeviceDescription.xml
SERVER: Linux/2.x.x, UPnP/1.0, pvConnect UPnP SDK/1.0, Twonky UPnP SDK/1.1
ST: upnp:rootdevice
USN: uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx::upnp:rootdevice
Content-Length: 0


-----------


# VAIO
----------- from ('xxx.xxx.x.12', 1900)
HTTP/1.1 200 OK
ST:upnp:rootdevice
USN:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx::upnp:rootdevice
Location:http://xxx.xxx.x.12:2869/upnphost/udhisapi.dll?content=uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
OPT:"http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS:3df856bdbb7820c23a43a6559076b14d
Cache-Control:max-age=900
Server:Microsoft-Windows-NT/5.1 UPnP/1.0 UPnP-Device-Host/1.0
Ext:


-----------

# SH-06E
----------- from ('xxx.xxx.x.8', 37577)
HTTP/1.1 200 OK
Cache-control: max-age=1800
Usn: uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxa::upnp:rootdevice
Location: http://xxx.xxx.x.8:58645/dev/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxa/desc.xml
Server: Linux/3.4.0 UPnP/1.0 BubbleUPnP/2.2.2
Ext: 
St: upnp:rootdevice


-----------
----------- from ('xxx.xxx.x.8', 37577)
HTTP/1.1 200 OK
Cache-control: max-age=1800
Usn: uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxb::upnp:rootdevice
Location: http://xxx.xxx.x.8:58645/dev/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxb/desc.xml
Server: Linux/3.4.0 UPnP/1.0 BubbleUPnP/2.2.2
Ext: 
St: upnp:rootdevice


-----------


# CMT-X7CD
----------- from ('xxx.xxx.x.5', 3911)
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=1800
EXT:
LOCATION: http://xxx.xxx.x.5:8080/description.xml
X-AV-Server-Info: av="5.0"; cn="Sony Corporation"; mn="CMT-X7CD(B)"; mv="1.00"
X-AV-Physical-Unit-Info: pa="CMT-X7CD(B)"
SERVER: KnOS/3.2 UPnP/1.0 DMP/3.5
ST: upnp:rootdevice
USN: uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx::upnp:rootdevice


-----------
----------- from ('xxx.xxx.x.5', 3911)
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=1800
EXT:
LOCATION: http://xxx.xxx.x.5:8000/serverxml.xml
X-AV-Server-Info: av="5.0"; cn="Sony Corporation"; mn="CMT-X7CD(B)"; mv="1.00"
X-AV-Physical-Unit-Info: pa="CMT-X7CD(B)"
SERVER: KnOS/3.2 UPnP/1.0 DMP/3.5
ST: upnp:rootdevice
USN: uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx::upnp:rootdevice


-----------

# WZR-1750DHP2
----------- from ('xxx.xxx.x.200', 54848)
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=1810
DATE: Thu, 02 Jan 2014 19:30:08 GMT
EXT:
LOCATION: http://xxx.xxx.x.200:9001/TMSDeviceDescription.xml
SERVER: Linux/2.x.x, UPnP/1.0, pvConnect UPnP SDK/1.0, Twonky UPnP SDK/1.1
ST: upnp:rootdevice
USN: uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx::upnp:rootdevice
Content-Length: 0


-----------

あれ? Windowsがなんで反応するんだろうと思ったけどWindowsMediaPlayerがDLNAサポートしてるせいか。実験時にプレーヤーは起動してないけど裏でサービスが上がっている模様。それはさておき、なんでAndroid(BubbleUPnP)とNWスピーカー(CMT-X7CD)は2回応答してくるんだろう? という疑問は次回に続く。

SONY CMT-X7CD

本編と関係ないけど、今回NWスピーカーとして登場した「CMT-X7CD」はマルチコネクトコンポという現代のラジカセみたいなもの。CDも聴けるしradikoも聞けるしNASの音楽も聴ける。ついでにBTスピーカーにもなるのです。

CMT-X7CD | システムステレオ | ソニー

電源投入後の起動が遅いのが玉に瑕ですが、スマホから(BT経由で)リモコン操作もできるのでなかなか良いです*4


*1:DLNA Certificationしてるかどうかはさておき、使える機器

*2:Twonky ServerのOEMっぽい

*3:てことはつまりChromecastの仕組上、端末側はUPnPでキャスト先を検出してるってことね

*4:M-SEARCHレスポンスにあるKnOSが何者なのかが気になるところ