UPnP的介紹和理解

前言

做android智能硬件開發一年,藍牙接觸多的就是spp模擬串口通信,而更多的是upnp,因爲大部分的項目都是基於cling庫的wifi方案的項目。設備的wifi方案相對於藍牙方案,傳輸速度快,覆蓋範圍廣,能夠脫離設備獨立聯網,協議規範簡單明瞭,但價格相對要高一些。

cling庫地址:
http://4thline.org/projects/cling/

UPnP簡介

upnp是 universal plug and play,即:即插即用設備,可以當作是一個相對複雜的網絡協議,畢竟它包含了很多其他的網絡協議,如:ip(設備尋址),tcp、udp(數據打包發送)、http(數據傳遞格式)等。

upnp可以擴展,也就是說你還可以在啓動加入其他的協議,比如:傳遞數據時,http協議再包一層json協議,或者數據傳遞使用xml協議來傳遞等等。

upnp之所以強大,感覺很大一個原因是基於互聯網,這樣對等設備可以通過互聯網自由交互,也就是說任何可以聯網的設備都可以使用upnp協議。

UPnP工作步驟

有興趣的可以去看看這個upnp文檔:

英文版ppt介紹:
http://101.96.10.63/trinea.github.io/doc/upnp/UPnP_UDA_tutorial_July2014.pdf

中文版文檔介紹:
http://read.pudn.com/downloads37/doc/comm/125876/UDA1.0-ChinesePDF.pdf

工作步驟其實只是一個工作的邏輯,大概的按功能劃分爲6個步驟,如下圖1所示:

upnp工作步驟

工作流程如下圖2所示:

這裏寫圖片描述

0、尋址-Addressing

既然基於互聯網,那麼基本的p2p協議需要滿足,所以尋址算是upnp的基礎。

所以就必須要有尋址,尋址的過程就是設備獲取ip地址的過程,這個裏面一般都使用DHCP(Dynamic Host Configuration Protocol,動態主機配置協議),即路由動態的分配一個沒有使用的ip地址給設備。

1、發現-Discovery

既然來到了互聯網的大世界,通過尋址有了身份標識ip,閒的無聊那麼必然就要找個小夥伴交流溝通,當然最好是妹子,所以這時候就有了一個發現的概念。

首先你要先自我介紹,也就是網絡中的控制點介紹自己(是什麼、能幹什麼),因爲不知道當前世界有多少個控制點,所以一般通過喊話的形式來介紹自己。也就是說新加入的設備以多播的形式廣播自己的信息。

當然如果作爲一個控制點,也有權限搜索自己感興趣的設備。搜的時候控制點自己不知道有沒有自己感興趣的設備。同樣這也是通過多播的形式,當世界的另一端乖妹子聽到了這個信息,那麼就會以單獨的形式應答,這就是單播響應。就相當於面試一樣,公司要找一個美工妹子,發佈一個廣告,添加要求福利待遇,然後留個郵箱,感興趣的美工妹子們就會發簡歷到這個郵箱。人可以喊,公司可以登招聘廣告,但是設備不可以。那麼設備是怎麼做到的,設備是依託於ssdp(Simple Service Discovery Protocol)簡單服務發現協議,這個協議類似定義了怎麼喊,喊的格式,怎麼登招聘廣告,廣告的格式是怎麼樣的。如下所示:

  • 設備介紹自己(喊話介紹自己格式)
NOTIFY * HTTP/1.1 (標準的http1.1協議)
HOST: 239.255.255.250:1900(路由固定的多播地址和端口 互聯網編號分配組織很強勢的定義好了的)
CACHE-CONTROL: max-age = seconds until advertisement expires 指代廣播有效持續時間
LOCATION: URL for UPnP description for root device
NT: search target 設備類型
NTS: ssdp:alive
USN: advertisement UUID 複合標識符

其中特別說明的是LOCATION,LOCATION是關於設備更多信息的 URL 地址(或有關服務的內含設備),這也就是描敘設備信息的一個文檔地址,後面會用到。

  • 控制點搜索(公司發佈招聘廣告格式)
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900(路由固定的多播地址和端口 互聯網編號分配組織很強勢的定義好了的)
MAN: "ssdp:discover"
MX: seconds to delay response
ST: search target

這裏需要注意的是ssdp其實包含兩個簡單協議,即:HTTPMU、HTTPU。HTTPMU(Http Multicast UDP)是http協議的變種,即通過udp的方式組播發送http格式的內容,HTTPU即通過udp的方式發送單播給host。

2、描述-Description

既然有了尋找小夥伴的方式,那麼怎麼挑選小夥伴呢?發現直接能得到的只有一些簡單的標識信息,如設備(或服務)的 UPnP 類型、設備的全球唯一標識符和設備 UPnP 描述的 URL 地址。而要了解一個小夥伴當然是不夠的,就相當於招聘光靠簡歷個人簡介是完全不夠了,還需要了解他的長相身材,工作能力以及性格價值觀等

所以就需要獲取設備描述,那麼怎麼獲取呢?對的,怎麼獲取,其實在設備發現的時候就已經把設備描述帶出來了,只是封裝在一個url中,也就是LOCATION中的描述url,通過location中的url能獲取一個xml,一般設備的描述都是通過xml來標識的。

設備描述一般包含兩個部分:描述所包含的物理與邏輯設備、一個或多個服務描述(描述設備對外暴露的能力)。也就相當於物體除了基本的外觀名稱以外,還包括他能幹什麼。設備描述包括特定廠商、製造商信息,如模塊名稱和編號、序列號、製造商名稱、特定廠商網站 URL 等(詳細信息如下)。對於設備中的每種服務,設備描述都包含服務類型、名稱、服務描述 URL、控制 URL 以及事件 URL。設備描述還包含所有嵌入式設備描述與 URL 地址集。
如下所示:

<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
 <specVersion>
 <major>1</major>
 <minor>0</minor>
 </specVersion>
 <URLBase>base URL for all relative URLs</URLBase>
 <device> 
 <deviceType>urn:schemas-upnp-org:device:deviceType:v</deviceType>
 <friendlyName>short user-friendly title</friendlyName>
 <manufacturer>manufacturer name</manufacturer>
 <manufacturerURL>URL to manufacturer site</manufacturerURL>
 <modelDescription>long user-friendly title</modelDescription>
 <modelName>model name</modelName>
 <modelNumber>model number</modelNumber>
 <modelURL>URL to model site</modelURL>
 <serialNumber>manufacturer's serial number</serialNumber>
 <UDN>uuid:UUID</UDN>
 <UPC>Universal Product Code</UPC>
 <iconList>
 <icon>
 <mimetype>image/format</mimetype>
 <width>horizontal pixels</width>
 <height>vertical pixels</height>
 <depth>color depth</depth>
 <url>URL to icon</url>
 </icon>
 XML to declare other icons, if any, go here
 </iconList>
 <!--以上是信息描敘,以下是能力行爲描敘-->
 <serviceList>
 <service>
 <serviceType>urn:schemas-upnp-org:service:serviceType:v</serviceType>
 <serviceId>urn:upnp-org:serviceId:serviceID</serviceId>
 <SCPDURL>URL to service description</SCPDURL>
 <controlURL>URL for control</controlURL>
 <eventSubURL>URL for eventing</eventSubURL>
 </service>
 Declarations for other services defined by a UPnP Forum working committee (if any)
 go here
 Declarations for other services added by UPnP vendor (if any) go here
 </serviceList>
 <!--以上是能力行爲描敘,以下是從設備描述-->
 <deviceList>
 Description of embedded devices defined by a UPnP Forum working committee (if any)
 go here
 Description of embedded devices added by UPnP vendor (if any) go here
 </deviceList>
 <presentationURL>URL for presentation</presentationURL>
 </device>
</root>

這裏需要值得注意的是:能力行爲的描述也就是:

 <service>
 <serviceType>urn:schemas-upnp-org:service:serviceType:v</serviceType>
 <serviceId>urn:upnp-org:serviceId:serviceID</serviceId>
 <SCPDURL>URL to service description</SCPDURL>
 <controlURL>URL for control</controlURL>
 <eventSubURL>URL for eventing</eventSubURL>
 </service>
  • serviceType
    描述UPnP 服務類型,固定格式:urn:domain-name:service:serviceType:v
  • serviceId
    服務標識符,固定格式urn:domain-name:serviceId:serviceID,一般應用中訪問就需要通過serviceId來調用相關的服務
  • SCPDURL
    服務描述的 URL,url中細節描述了服務包含的action,參數等。後面控制訂閱都需要用到。
  • controlURL
    控制的 URL,調用服務的action必須要通過這個url來調用,就相當於一個控制服務的地址
  • eventSubURL
    事件的 URL,如果服務沒有事件,則該元素必須展示出來,但是應該爲空。

下面看看標準SCPDURL中的內容:

<?xml version="1.0"?>
<scpd xmlns="urn:schemas-UPnP-org:service-1-0">
 <!--要求upnp的架構版本-->
 <specVersion>
 <major>1</major>
 <minor>0</minor>
 </specVersion>
 <!--action列表-->
 <actionList>
 <action>
 <!--action名稱-->
 <name>actionName</name>
 <!--參數列表-->
 <argumentList>
 <argument>
 <!--參數名稱-->
 <name>formalParameterName</name>
 <!--參數是入參還是出參-->
 <direction>in xor out</direction>
 <retval />
 <!--必須是一個狀態變量的名稱,文檔後面狀態變量的表會對應其類型和取值範圍等,就類似類中的某個屬性值的名稱-->
 <relatedStateVariable>stateVariableName</relatedStateVariable>
 </argument>
 </argumentList> 
 </actionList> 
 <!--狀態變量的表-->
 <serviceStateTable>
 <!--sendEvents標識變量值發生變化需不需要回調通知狀態改變-->
 <stateVariable sendEvents="yes">
 <!--狀態變量的名稱-->
 <name>variableName</name>
 <!--狀態變量的數據類型-->
 <dataType>variable data type</dataType>
 <!--狀態變量的初始化的值-->
 <defaultValue>default value</defaultValue>
 <!--狀態變量的允許設置的值-->
 <allowedValueList>
 <allowedValue>enumerated value</allowedValue>
Other allowed values defined by UPnP Forum working committee (if any) go here
 </allowedValueList>
 </stateVariable>
 <stateVariable sendEvents="yes">
 <name>variableName</name>
 <dataType>variable data type</dataType>
 <defaultValue>default value</defaultValue>
 <!--狀態變量的允許設置的值範圍-->
 <allowedValueRange>
 <minimum>minimum value</minimum>
 <maximum>maximum value</maximum>
 <step>increment value</step>
 </allowedValueRange>
 </stateVariable>
Declarations for other state variables defined by UPnP Forum working committee
(if any) go here
Declarations for other state variables added by UPnP vendor (if any) go here
 </serviceStateTable>
</scpd>

在實際使用當中,service就相當於一個類,狀態變量就相當於類的全局變量,一定別訂閱,發生變化就要通知訂閱者更新,而service中對應的action就相當於類中的方法。

3、控制-Control

既然有了身份標識,發現了小夥伴,那麼控制就自然而然很重要了。其實控制就相當於領導和你溝通工作,讓你幹啥,你幹完了給領導個反饋。

那麼控制是怎麼實現的呢?一個控制的過程包含 控制地址、控制說明、控制執行、控制響應。

  • 控制地址

發送控制命令,首先得有控制的地址,所以描述中的control url就是需要的控制地址,相當於你找到你的新玩具的控制開關的模塊。

  • 控制說明

找到了控制模塊那麼你需要知道怎麼控制,這時候你就需要說明書了,而對於設備,描述中的scpd url,就詳細表明瞭設備提供的功能和操作步驟。

  • 控制執行

閱讀完說明書,那麼就需要你執行命令了。設備命令的執行傳遞依託於tcp/ip協議,而內容的封裝在http協議中,但是http協議的內容光做展示可能比較合適,但是做命令的封裝可能就相對較弱,所以upnp在http中增加了標準的交換數據的一種協議 soap(簡單對象訪問協議),soap協議簡單、輕量、而且是基於xml協議的,所以內容格式可以看出是xml的語法結構,下面就看看具體的參考報文格式:

POST path of control URL HTTP/1.1
HOST: host of control URL:port of 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>
other in args and their values go here, if any
 </u:actionName>
 </s:Body>
</s:Envelope>

關於soap協議的介紹可以參考 w3c soap教程

  • 控制響應
    每個控制都需要有迴應,就相當於你去播放cd一樣,如果你執行了播放命令,沒有聲音播放,你會感覺很奇怪,會思考是不是音量太小或者壞叼了。所以一個控制命令執行後沒有控制的響應也就不清楚命令執行的狀況。下面看看標準的控制響應的報文:
HTTP/1.1 200 OK
CONTENT-LENGTH: bytes in body
CONTENT-TYPE: text/xml; charset="utf-8"
DATE: when response was generated
EXT:
SERVER: OS/version UPnP/1.0 product/version
<s:Envelope
 xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 <s:Body>
 <u:actionNameResponse xmlns:u="urn:schemas-upnp-org:service:serviceType:v">
 <argumentName>out arg value</argumentName>
other out args and their values go here, if any
 </u:actionNameResponse>
 </s:Body>
</s:Envelope>

4、事件-Eventing

事件即設備的狀態量發生了變化,使用觀察者模式,首先觀察某個狀態量就需要註冊一個觀察者,當狀態量發生變化的時候,設備就會提示觀察者狀態量發生變化,請及時處理,有關於觀察者可以去看看著名的氣象局的例子,在upnp協議中事件協議是用的是GENA協議(Generic Event Notification Architecture)。下面是報文格式。

  • 訂閱事件
SUBSCRIBE publisher path HTTP/1.1
HOST: publisher host:publisher port
CALLBACK: <delivery URL>
NT: upnp:event
TIMEOUT: Second-requested subscription duration
  • 取消訂閱
UNSUBSCRIBE publisher path HTTP/1.1
HOST: publisher host:publisher port
SID: uuid:subscription UUID
  • 消息訂閱
NOTIFY delivery path HTTP/1.1
HOST: delivery host:delivery port
CONTENT-TYPE: text/xml
CONTENT-LENGTH: Bytes in body
NT: upnp:event
NTS: upnp:propchange
SID: uuid:subscription-UUID
SEQ: event key
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
 <e:property>
 <variableName>new value</variableName>
 </e:property>
Other variable names and values (if any) go here.
</e:propertyset>

5、展示-Presentation

展示作爲一個控制和事件的補充,實現upnp協議並不強制要求。其實就是一個網頁,可以看到設備的信息和狀態,做的好的還可以對設備進行控制。如果提供的完整的話就可以不需要什麼應用,一個網頁就可以查看設備的基本信息,控制設備的基本操作。

UPnP總結

上面詳細的說明了upnp的協議的介紹,其實用一個圖就可以全部概括起來,如下圖3:

upnp總結

  1. 尋址

    UPnP 網絡互連的基礎是基於DHCP或AutoIP的 IP 尋址。這也是p2p協議的基礎,就相當於獲取身份標識的ID(身份 證)。

  2. 發現
    如果獲取了一個 IP 地址,則 UPnP 網絡的第 1 步是發現。在將一個設備添加到網絡上之後,UPnP 發現協議允許該設備向網絡中的控制點宣告其服務。同樣,當一個控制點被添加到網絡後,UPnP 發現協議允許該控制點在網上搜索
    感興趣的設備。這兩者處理上都需要HTTPMU協議支持。ssdp協議是支撐發現的基礎。

  3. 描述
    UPnP 網絡中的第 2 步是描述。控制點在發現一個設備之後仍然對其知之甚少。爲了使控制點瞭解到更多關於設備及其能力的信息或與設備進行交互,則控制點必須取得來自該設備在發現消息中所提供之 URL 的設備描述。描述的基礎是發現,如果沒有發現獲取到設備的最基礎的信息,得不到location中的設備描述url,也就沒有設備能力這一說。

  4. 控制
    UPnP 網絡中的第 3 步是控制。當一個控制點取得設備描述後,該控制點可將動作發至一個設備的服務。爲此,控制點將一條適當的控制消息發至服務的控制 URL(在設備描述中提供)。控制消息同樣利用簡單對象訪問協議(SOAP)通過 XML 來表達。

  5. 事件
    UPnP 網絡的第 4 步是事件觸發。針對服務的 UPnP 描述包括一個服務響應的動作列表,以及一個對服務器運行時狀態進行展示的變量列表。在這些變量變更時服務會發布更新,一個控制點可以預訂接收此信息。服務通過發送事件消息來發布更新。事件消息包含一個或多個狀態變量名和這些變量的當前值。這些消息同樣通過 XML 來表達,並採用通用事件通知架構(GENA)格式。

  6. 展示
    UPnP 網絡中的第 5 步是展示。如果設備有用於展示的 URL,那麼控制點就可以通過此 URL 取得一個頁面,在瀏覽器中加載該頁面,並且根據頁面的功能,支持用戶控制設備和/或瀏覽設備狀態。每一項完成的程度取決於展示頁面
    和設備的具體功能。

其實cling庫upnp協議的實現,框架本身就是通過代碼來提供報文格式的封裝,使用者能夠動態確定設備交互報文的內容。有時間分享一下cling的源碼分析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章