前面公司有DLNA項目,研究了一下,在網上關於DLNA的資源很少,就將自己的心得寫出來,以供參考。
其它的關於DLNA的介紹就不多說,要了解DLNA需要了解upnp,因為DLNA在upnp之上,初學者可以從http://www.upnp.org下載upnp的資料.也歡迎大家加入197683240 DLNA交流群。
upnp分為四步:發現 、描述 、控制 、事件
發現
當一個UPnP的設備加入網絡,並想知道什么UPnP服務在網絡上可用,它發送一個發現消息多播地址239.255.255.250端口1900通過UDP協議。此消息包含一個頭,類似於一個HTTP請求。該協議有時被稱為為HTTPU(HTTP通過UDP):
M-SEARCH * HTTP/1.1
ST: upnp:rootdevice
MX: 3
MAN: "ssdp:discover"
所有其他UPnP設備或方案都必須回應此消息類似的消息發送回設備,使用UDP單播,宣布該設備或程序實現的UPnP型材。一個有趣的怪癖:發送UDP單播設備發現消息被送往港口。對於每一個配置文件,它實現發送一條消息:
HTTP/1.1 200 OK
ST:upnp:rootdevice
USN:uuid:1d8ec8a7-4736-4598-9950-9710c992e471::upnp:rootdevice
Location:http://172.16.11.205:2869/upnphost/udhisapi.dll?content=uuid:1d8ec8a7-4736-4598-9950-9710c992e471
OPT:"http://schemas.upnp.org/upnp/1/0/";ns=0101-NLS:a06cdf4dcc4f213129a39f9b2ae98977
Cache-Control:max-age=3200
Server:Microsoft-Windows-NT/5.1 UPnP/1.0UPnP-Device-Host/1.0
在定期間隔的UPnP功能的設備或程序發送一條消息,宣布他們的服務。一個通知消息是或多或少相同,但發現響應消息發送到239.255.255.250組播地址通過UDP 1900端口上的UPnP有ST頭,取而代之的是一個類似頭NT頭。
描述
每個配置文件提供了本身的描述和它提供的服務,並通過XML提供。從發現階段的響應消息中包含一個頭稱為位置(不區分大小寫),這是一個XML格式的文件可以下載的網址。這個文件描述(或相當:應說明)配置文件,設備或計划實施,控制和事件相應命令發送到專門的網址,但也可能是其他有關設備的元信息,如圖標,這應該是顯示Windows資源管理器,設備制造商,依此類推。
有沒有這個頭文件的默認值。事實上,在一些設備,尤其是對一個Broadcom芯片為基礎的,它被設置在啟動時動態。唯一的方法是完全肯定的是永遠做設備發現。
控制
在該協議的第三步是“控制”:設備或程序可以要求其他設備或程序執行客戶的名義采取行動,使用SOAP。 SOAP是一個協議,運行在HTTP上使用XML來描述遠程過程調用服務器和從這些調用的返回結果。 SOAP主要用於基於網絡的服務。對於每一個主要的編程語言庫,可以用來實現SOAP請求和處理SOAP響應。
請求服務是通過發送一個SOAP請求到正確的參數,所謂的“控制URL”的控制點。為控制特定的配置文件的URL地址,可以發現在XML文件的URL在Location頭從描述階段發現內的<service>標簽。配置文件標記看起來像這樣:
<service>
<serviceType>urn:dmc-samsung-com:service:SyncManager:1</serviceType>
<serviceId>urn:dmc-samsung-com:serviceId:SyncManager</serviceId>
<controlURL>/upnphost/udhisapi.dll?control=uuid:1d8ec8a7-4736-4598-9950-9710c992e471+urn:dmc-samsung-com:serviceId:SyncManager</controlURL>
<eventSubURL>/upnphost/udhisapi.dll?event=uuid:1d8ec8a7-4736-4598-9950-9710c992e471+urn:dmc-samsung-com:serviceId:SyncManager</eventSubURL>
<SCPDURL>/upnphost/udhisapi.dll?content=uuid:bdccc2ab-dcdf-4c18-beee-226cc7df1f94</SCPDURL>
</service>
只發送SOAP請求URL內controlURL標簽是必要的。這取決於哪些行動可以執行的配置文件。在在SCPDURL標記的URL的URL是所謂的“服務描述的URL”。它描述了SOAP方法可以進行該配置什么所謂的狀態變量配置文件。在這個文件是什么,應符合設備提供服務,但在實踐中,他們似乎總是不相匹配。
事件
UPnP中有這樣的概念,被稱為“狀態變量”。這些變量,因為這個名字說,用於保持某種形式的狀態中的UPnP設備和方案。一個程序可以訂閱狀態的變化:當狀態變量改變時,新的狀態被發送到所有程序/設備已訂閱的事件。程序/設備可以訂閱一個服務的狀態變量,並簽署一個網址,可以發現所指出的位置的URL。
<service>
<serviceType>urn:dmc-samsung-com:service:SyncManager:1</serviceType>
<serviceId>urn:dmc-samsung-com:serviceId:SyncManager</serviceId>
<controlURL>/upnphost/udhisapi.dll?control=uuid:1d8ec8a7-4736-4598-9950-9710c992e471+urn:dmc-samsung-com:serviceId:SyncManager</controlURL>
<eventSubURL>/upnphost/udhisapi.dll?event=uuid:1d8ec8a7-4736-4598-9950-9710c992e471+urn:dmc-samsung-com:serviceId:SyncManager</eventSubURL>
<SCPDURL>/upnphost/udhisapi.dll?content=uuid:bdccc2ab-dcdf-4c18-beee-226cc7df1f94</SCPDURL>
</service>
描述文件如:
<?xml version="1.0" ?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<deviceType>urn:dmc-samsung-com:device:SyncServer:1</deviceType>
<friendlyName>QPC-20120228LBE</friendlyName>
<manufacturer>Samsung-Electronics</manufacturer>
<manufacturerURL>http://www.samsung.com</manufacturerURL>
<modelDescription>QPC-20120228LBE-Laptop</modelDescription>
<modelName>Kies Sync Server</modelName>
<modelNumber>1.0</modelNumber>
<modelURL>http://www.samsung.com</modelURL>
<UDN>uuid:1d8ec8a7-4736-4598-9950-9710c992e471</UDN>
<serviceList>
<service>
<serviceType>urn:dmc-samsung-com:service:SyncManager:1</serviceType>
<serviceId>urn:dmc-samsung-com:serviceId:SyncManager</serviceId>
<controlURL>/upnphost/udhisapi.dll?control=uuid:1d8ec8a7-4736-4598-9950-9710c992e471+urn:dmc-samsung-com:serviceId:SyncManager</controlURL>
<eventSubURL>/upnphost/udhisapi.dll?event=uuid:1d8ec8a7-4736-4598-9950-9710c992e471+urn:dmc-samsung-com:serviceId:SyncManager</eventSubURL>
<SCPDURL>/upnphost/udhisapi.dll?content=uuid:bdccc2ab-dcdf-4c18-beee-226cc7df1f94</SCPDURL>
</service>
</serviceList>
</device>
</root>
1.搜索目前網絡上的UPnP設備。Control Point生成一個MulticastSocket,綁定多播地址239.255.255.250 1900端口,然后發送一個搜索請求,默認將TimeToLive設為4,該請求在UPnP Device Architecture中是如下定義的:
M-SEARCH *HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: seconds to delay response
ST: search target
要注意的一點,該請求基於 HTTPMU(HTTP Multicast over UDP),上面這些信息都是屬於HTTP Header,沒有HTTP Body,而HTTP Header和HTTP Body之間是有一個空白行分隔的,通過Socket發送出去的時候不要忘了發送那個空白行,以后提到的消息也都請注意這一點。
UPnP設備收到該請求后會延時相當於Random.nextInt(MX)返回響應,以便Control Point能夠有充足時間來處理請求;ST是要搜索的目標,如果搜索所有的設備和服務,則為ssdp:all,如果是搜索根設備,則為 upnp:rootdevice,象大部分程序中使用UPnP是為了找到支持UPnP的網關來動態映射端口,則可以賦為urn:schemas-upnp-org:device:InternetGatewayDevice:1。
下面是一個示例,搜索所有的根設備,這些設備收到該消息后應該在0~3秒內返回響應:
M-SEARCH* HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 3
ST: upnp:rootdevice
2.網絡上的UPnP設備返回響應。如果該UPnP設備和要搜索的UPnP設備匹配,則該設備會返回一個響應,響應的格式在UPnP Device Architecture中是如下定義的:
HTTP/1.1200 OK
CACHE-CONTROL: max-age = seconds untiladvertisement expires
DATE: when response was generated
EXT:
LOCATION: URL for UPnP description for root device
SERVER: OS/version UPnP/1.0 product/version
ST: search target
USN: advertisement UUID
max-age表示收到該消息后若干秒內沒有收到該設備發出的任何通知消息,就認為該設備已經不存在網絡上了;LOCATION表示該設備的描述文件,用於確定該設備包含哪些邏輯設備和哪些服務等等;USN表示Unique Service Name。
比如對於上面那條示例搜索消息,我的ADSL返回的響應是:
HTTP/1.1 200 OK
CACHE-CONTROL:max-age=1800
EXT:
LOCATION:http://10.0.0.138:80/IGD.xml
SERVER:SpeedTouch 510 4.0.2.0.1 UPnP/1.0 (14E31Y7)
ST:upnp:rootdevice
USN:uuid:UPnP-SpeedTouch510-1_00-90-D0-7F-AD-37::upnp:rootdevice
3.接下來就是取得該設備的描述文件,用於確定該設備信息和所支持的 功能。通過上面的響應信息的LOCATION屬性,可以得到一個URL,可以通過HTTP請求該URL得到該設備的描述文件。注意,僅僅在搜索和通知的時 候是基於UDP的,其余的都是基於TCP的。設備描述文件定義可在UPnP Device Architecture中找到,比較長就不貼了。
比如上面我的ADSL返回LOCATION是http://172.16.11.205:80/IGD.xml,訪問該地址,返回的一個XML片斷是:
<?xmlversion="1.0" ?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://172.16.11.205</URLBase>
<device>
<deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType>
<friendlyName>SpeedTouch 510 (14E31Y7)</friendlyName>
<manufacturer>THOMSON multimedia</manufacturer>
<manufacturerURL>http://www.thomson-multimedia.com</manufacturerURL>
<modelDescription>DSL Internet Gateway</modelDescription>
<modelName>SpeedTouch</modelName>
<modelNumber>510</modelNumber>
<modelURL>http://www.speedtouch.com</modelURL>
<serialNumber>14E31Y7</serialNumber>
<UDN>uuid:UPnP-SpeedTouch510-1_00-90-D0-7F-AD-37</UDN>
<presentationURL>/index.htm</presentationURL>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType>
<serviceId>urn:upnp-org:serviceId:layer3f</serviceId>
<controlURL>/upnp/control/layer3f</controlURL>
<eventSubURL>/upnp/event/layer3f</eventSubURL>
<SCPDURL>/Layer3Forwarding.xml</SCPDURL>
</service>
</serviceList>
<deviceList>
......
</deviceList>
</device>
</root>
在UPnP規范中規定,一個設備可以包含若干的嵌入設備和服務。比如對於最常用到的InternetGateway Device中,UPnP InternetGatewayDevice模板中規定
可以看到在根設備中包含了Layer3 Forwarding Service和兩個嵌入設備:WANDevice和LANDevice,而WANDevice下面又包含了若干WANConnectionDevice等等。
4.得到設備所提供的服務描述。在剛才的設備描述中有一個ServiceList節點,該節點下每個Service節點都包含一個SCPDURL節點,這個就是服務描述文件所在的位置,比如上面我的ADSL中Layer3 Forwarding Service服務描述文件的位置就是/Layer3Forwarding.xml,再組合URLBase節點屬性值http://172.16.11.205,即得到該服務描述文件URL為http://172.16.11.205/Layer3Forwarding.xml,該文件詳細的描述了該服務所提供的操作列表以及相應的參數和參數范圍。
5.調用服務所提供的操作。調用是通過發送相應SOAP消息到該服務的控制URL上來完成的。該信息在UPnP Device Architecture中是如下定義的:
POST path of control URL HTTP/1.1
HOST: host of control URL:portof control URL
CONTENT-LENGTH: bytes in body
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:serviceType:v#actionName"
<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:actionName xmlns:u="urn:schemas-upnp-org:service:serviceType:v">
<argumentName>in arg value</argumentName>
otherin args and their values go here, if any
</u:actionName>
</s:Body>
</s:Envelope>
就用在IGD設備上增加端口映射這個操作來舉例,將網關的5678端口映射到內網10.0.0.1的8765端口,該操作被發送的SOAP消息如下:
POST/upnp/control/wanpppcpppoe HTTP/1.0
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: 172.16.11.205:80
CONTENT-LENGTH: 649
SOAPACTION: "urn:schemas-upnp-org:service:WANPPPConnection:1#AddPortMapping"
<?xmlversion="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:AddPortMappingxmlns:u="urn:schemas-upnp-org:service:WANPPPConnection:1">
<NewRemoteHost></NewRemoteHost>
<NewExternalPort>5678</NewExternalPort>
<NewProtocol>tcp</NewProtocol>
<NewInternalPort>8765</NewInternalPort>
<NewInternalClient>10.0.0.1</NewInternalClient>
<NewEnabled></NewEnabled>
<NewPortMappingDescription></NewPortMappingDescription>
<NewLeaseDuration></NewLeaseDuration>
</u:AddPortMapping>
</s:Body>
</s:Envelope>
操作成功,設備的返回值是:
HTTP/1.0200
CONTENT-TYPE: text/xml; charset="utf-8"
SERVER: SpeedTouch 510 4.0.2.0.1 UPnP/1.0 (14E31Y7)
CONTENT-LENGTH: 304
Connection: close
EXT:
<?xmlversion="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<m:AddPortMappingResponsexmlns:m="urn:schemas-upnp-org:service:WANPPPConnection:1"></m:AddPortMappingResponse>
</s:Body>
</s:Envelope>
6.在設備一些屬性變化了的時候,如果ControlPoint訂閱了它的事件通知,則它會發送相應的通知給Control Point。在androiddlnaplayer中有個SSDPNotifySocketList來完成此事。ControlPoint注冊后通過deviceNotifyReceived回調來通知ControlPoint。
SSDP協議消息
3.1 設備通知消息
在設備加入網絡,UPnP發現協議允許設備向控制點廣告它的服務。它使用向一個標准地址和端口多址傳送發現消息來實現。控制點在此端口上偵聽是否有新服務加入系統。為了通知所有設備,一個設備為每個其上的嵌入設備和服務發送一系列相應的發現消息。每個消息也包含它表征設備或服務的特定信息。
3.1.1 ssdp:alive消息
在設備加入系統時,它采用多播傳送方式發送發現消息,包括告知設備包含的根設備信息,所有嵌入設備以及它包含的服務。每個發現消息包含四個主要對象:
- 在NT頭中包含的潛在搜索目標。
- 在USN頭中包含的復合發現標識
- 在LOCATION頭中關於設備信息的URL地址
- 在CACHE-CONTROL頭中表示的廣告消息的合法存在時間。
對於根設備,存在三種發現消息:
NT |
USN |
根設備的UUID |
根設備的UUID |
設備類型:設備版本 |
根設備的UUID,設備類型:設備版本 |
upnp:rootdevice |
根設備的UUID,設備類型和upnp:rootdevice |
對於根設備,存在兩種發現消息:
NT |
USN |
嵌入設備的UUID |
嵌入設備的UUID |
設備類型:設備版本 |
嵌入設備的UUID,設備類型和設備版本 |
對於每個服務:
NT |
USN |
服務類型:服務版本 |
相關設備的UUID,服務類型和服務版本 |
如果一個根設備有n個嵌入設備,m個嵌入服務,而且包含k個不同的服務類型,這將會發出3+ 2n + k次請求。這些廣告消息像控制點描述了設備的所有信息。這些消息必須作為一系列一起發出,發送的順序無關緊要,但是不能對單個消息進行刷新或取消的操作。選擇一個適當的持續期是在最小化網絡通訊和最大化設備狀態及時更新之間求得一個平衡,相對較短的持續時間可以保證控制點在犧牲網絡流量的前提下獲得設備的當前狀態;持續期越長可以大大減少設備刷新造成的網絡流量。一般而言,設備制造商應該選擇一個適當的持續時間值。
由於UDP協議是不可信的,設備應該發送多次設備發現消息。而且為了降低控制點無法收到設備或服務廣告消息的可能性,設備應該定期發送它的廣告消息。在設備加入網絡時,它必須用NOTIFY方法發送一個多播傳送請求。NOTIFY方法發送的請求沒有回應消息,典型的設備通知消息格式如下:
NOTIFY * HTTP/1.1 HOST: 239.255.255.250:1900CACHE-CONTROL: max-age = seconds until advertisement expires LOCATION: URL for UPnP description for root device NT: search target NTS: ssdp:alive USN: advertisement UUID |
各HTTP協議頭的含義簡介:
HOST |
設置為協議保留多播地址和端口,必須是239.255.255.250:1900。 |
CACHE-CONTROL |
max-age指定通知消息存活時間,如果超過此時間間隔,控制點可以認為設備不存在 |
LOCATION |
包含根設備描述得URL地址 |
NT |
在此消息中,NT頭必須為服務的服務類型。 |
NTS |
表示通知消息的子類型,必須為ssdp:alive |
USN |
表示不同服務的統一服務名,它提供了一種標識出相同類型服務的能力。 |
一個發現響應可以包含0個、1個或者多個服務類型實例。為了做出分辨,每個服務發現響應包括一個USN:根設備的標識。在同樣的設備里,一個服務類型的多個實例必須用包含USN:ID的服務標識符標識出來。例如,一個燈和電源共用一個開關設備,對於開關服務的查詢可能無法分辨出這是用於燈的。UPNP論壇工作組通過定義適當的設備層次以及設備和服務的類型標識分辨出服務的應用程序場景。這么做的缺點是需要依賴設備的描述URL。
3.1.2 ssdp:byebye消息
在設備和它的服務將要從網絡中卸載時,設備應該對於每個未超期的ssdp:alive消息多播方式傳送ssdp:byebye消息。但如果設備突然從網絡卸載,它可能來不及發出這個通知消息。因此,發現消息必須在CACHE-CONTROL包含超時值,如果不重新發出廣告消息,發現消息最后超時並從控制點的緩存中除去。典型的設備卸載消息格式如下:
NOTIFY * HTTP/1.1 HOST: 239.255.255.250:1900NT: search target NTS: ssdp:byebye USN: advertisement UUID各HTTP協議頭的含義簡介: HOST 設置為協議保留多播地址和端口,必須是239.255.255.250:1900 NT 在此消息中,NT頭必須為服務的服務類型。 NTS 表示通知消息的子類型,必須為ssdp:alive USN 表示不同服務的統一服務名,它提供了一種標識出相同類型服務的能力。 |
3.2 設備查詢消息
當一個控制點加入到網絡中時,設備發現過程允許控制點尋找網絡上感興趣的設備。發現消息包括設備的一些特定信息或者某項服務的信息,例如它的類型、標識符、和指向XML設備描述文檔的指針。從設備獲得響應從本質上說,內容與多址傳送的設備廣播相同,只是采用單址傳送方式。設備查詢通過HTTP協議擴展M-SEARCH方法實現的。典型的設備查詢請求消息格式:
M-SEARCH * HTTP/1.1 HOST: 239.255.255.250:1900 MAN: "ssdp:discover" MX: seconds to delay response ST: search target |
各HTTP協議頭的含義簡介:
HOST |
設置為協議保留多播地址和端口,必須是239.255.255.250:1900。 |
MAN |
設置協議查詢的類型,必須是"ssdp:discover"。 |
MX |
設置設備響應最長等待時間,設備響應在0和這個值之間隨機選擇響應延遲的值。這樣可以為控制點響應平衡網絡負載。 |
ST |
設置服務查詢的目標,它必須是下面的類型: |
在設備接收到查詢請求並且查詢類型(ST字段值)與此設備匹配時,設備必須向多播地址239.255.255.250:1900回應響應消息。典型:
HTTP/1.1 200 OK CACHE-CONTROL: max-age = seconds until advertisement expires DATE: when reponse was generated EXT: LOCATION: URL for UPnP description for root device SERVER: OS/Version UPNP/1.0 product/version ST: search target USN: advertisement UUID |
各HTTP協議頭的含義簡介:
CACHE-CONTROL |
max-age指定通知消息存活時間,如果超過此時間間隔,控制點可以認為設備不存在 |
DATE |
指定響應生成的時間 |
EXT |
向控制點確認MAN頭域已經被設備理解 |
LOCATION |
包含根設備描述得URL地址 |
SERVER |
飽含操作系統名,版本,產品名和產品版本信息 |
ST |
內容和意義與查詢請求的相應字段相同 |
USN |
表示不同服務的統一服務名,它提供了一種標識出相同類型服務的能力。 |
在所有的發現通知中,表示UPnP根設備描述的LOCATION和統一服務名(USN)必須提供。此外,在響應消息中查詢目標頭(ST)必須與LOCATION和統一服務名(USN)一起提供。
專有設備或服務可以不遵循標准的UPNP模版。但如果設備或服務提供UPNP發現、描述、控制和事件過程的所有對象,它的行為就像一個標准的UPNP設備或服務。為了避免命名沖突,使用專有設備命名時除了UPNP域之外必須包含一個前綴"urn:schemas-upnp-org"。在與標准模版相同時,應該使用整數版本號。但如果與標准模版不同,不可以使用設備復用和徽標。
簡單設備發現協議不提供高級的查詢功能,也就是說,不能完成某個具有某種服務的設備這樣的復合查詢。在完成設備或者服務發現之后,控制點可以通過設備或服務描述的URL地址完成更為精確的信息查詢。