UPnP中Control Point的基本流程

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.1 200 OK
CACHE-CONTROL: max-age = seconds until advertisement 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://10.0.0.138:80/IGD.xml,訪問該地址,返回的一個XML片斷是:

<?xml version="1.0" ?>
  <root xmlns="urn:schemas-upnp-org:device-1-0">
    <specVersion>
      <major>1</major>
      <minor>0</minor>
  </specVersion>
    <URLBase>http://10.0.0.138</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規範中規定,一個設備可以包含若干的嵌入設備和服務。比如對於最常用到的Internet Gateway Device中,UPnP InternetGatewayDevice模板中規定

可以看到在根設備中包含了Layer3 Forwarding Service和兩個嵌入設備:WANDevice和LANDevice,而WANDevice下面又包含了若干WANConnectionDevice等等。

4.得到設備所提供的服務描述

在剛纔的設備描述中有一個ServiceList節點,該節點下每個Service節點都包含一個SCPDURL節點,這個就是服務描述文件所在的位置,比如上面我的ADSL中Layer3 Forwarding Service服務描述文件的位置就是/Layer3Forwarding.xml,再組合URLBase節點屬性值http://10.0.0.138,即得到該服務描述文件URL爲http://10.0.0.138/Layer3Forwarding.xml,該文件詳細的描述了該服務所提供的操作列表以及相應的參數和參數範圍。

5.調用服務所提供的操作

調用是通過發送相應SOAP消息到該服務的控制URL上來完成的。該信息在UPnP Device Architecture中是如下定義的:

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>

就用在IGD設備上增加端口映射這個操作來舉例,將網關的5678端口映射到內網10.0.0.1的8765端口,該操作被髮送的SOAP消息如下:

POST /upnp/control/wanpppcpppoe HTTP/1.0
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: 10.0.0.138:80
CONTENT-LENGTH: 649
SOAPACTION: "urn:schemas-upnp-org:service:WANPPPConnection:1#AddPortMapping"

<?xml version="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:AddPortMapping xmlns: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.0 200 
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:

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 <s:Body>
  <m:AddPortMappingResponse xmlns:m="urn:schemas-upnp-org:service:WANPPPConnection:1"></m:AddPortMappingResponse>
 </s:Body>
</s:Envelope>

6.設備屬性變化

在設備一些屬性變化了的時候,如果Control Point訂閱了它的事件通知,則它會發送相應的通知給Control Point。這部分我還未研究透徹,有待進一步瞭解。
這些只是一個基本的Control Point的流程,詳細的部分可以訪問http://www.upnp.org/download/UPnPDA10_20000613.htm,看看UPnP Device Architecture,裏面有詳細的描述。

大部分程序員對UPnP的興趣只限於動態映射IGD設備端口,因此可以去看看IGD設備規範,網址是http://www.upnp.org/standardizeddcps/igd.asp

在Window下實現動態端口映射,要做的完美一點,最好是按照前面一篇文章說的步驟,首先檢測Window下ICF是否打開,打開的話就得調 用ICF的API在防火牆上打開相應的端口,要不多播信息這些都被防火牆攔截下來了,也就沒有辦法找到UPnP設備了。不少非微軟的應用都沒有注意這一 點,讓我在初步瞭解UPnP技術的時候鬱悶了半天,以爲Windows 2003取消了對UPnP的支持就沒有辦法在Windows 2003下使用UPnP設備了,最後才發現是防火牆惹得禍。

因此Windows支不支持UPnP沒有關係,如果不支持也只是限於沒有辦法調用微軟提供的API而已:)

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