zoukankan      html  css  js  c++  java
  • 【转】upnp协议简介(一)

     

    upnp协议简介(一)

     分类:

    UPnP全名是Universal Plug and Play,主要是微软在推行的一个标准。简单的来说,UPnP 最大的愿景就是希望任何设备只要一接上网络,所有在网络上的设备马上就能知道有新设备加入,这些设备彼此之间能互相沟通,更能直接使用或控制它,一切都不需要设定,完全的Plug and Play。

    -------------------------------------------------------------------------------------------------------

    关于UPnP协议栈

    UPnP设备体系结构包含了设备之间、控制点之间、设备和控制点之间的通信。完整的UPnP由设备寻址、设备发现、设备描述、设备控制、事件通知和基于Html的描述界面几部分构成。

    1. UPnP是一个多层协议构成的框架体系,每一层都以相邻的下层为基础,同时又是相邻上层的基础。直至达到应用层为止。该图中的最下面是就是IP和TCP,共两层,负责设备的IP地址。

    2. 三层是HTTP、HTTPU、HTTPMU,这一层,属于传送协议层。传送的是内容都经过“封装”后,存放在特定的XML文件中的。对应的SSDP、GENA、SOAP指的是保存在XML文件中的数据格式。到这一层,已经解决了UPnP设备的IP地址和传送信息问题。

    3. 第四层是UPnP设备体系定义,仅仅是一个抽象的、公用的设备模型。任何UPnP设备都必须使用这一层。

    4. 第五层是UPnP论坛的各个专业委员会的设备定义层,在这个论坛中,不同电器设备由不同的专业委员会定义,例如:电视委员会只负责定义网络电视设备部分,空调器委员会只负责定义网络空调设备部分……,依此类推。所有的不同类型的设备都被定义成一个专门的架构或者模板,供建立设备的时候使用。可以推知,进入这一层,设备已经被指定了明确用途。当然,这些都必须遵守标准化的规范。从目前看,UPnP已经可以支持大部分的设备:从电脑、电脑外设,移动设备和家用消费类电子设备等等,无所不包,随着这个体系的普及,将可能有更多的厂家承认这一标准,最终,可能演化为公认的行业标准。

    5. 最上层,也就是应用层,由UPnP设备制造厂商定义的部分。这一层的信息是由设备制造厂商来“填充” 的,这部分一般有设备厂商提供的、对设备控制和操作的底层代码,然后,就是名称序列号呀,厂商信息之类的东西。

    -------------------------------------------------------------------------------------------------------

     

    关于UPnP的一些术语

    ● UUID

    UUID含义是通用唯一识别码(Universally Unique Identifier),其目的是让分布式系统中的所有元素,都有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。其格式为xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),分别为当前日期和时间,时钟序列,全局唯一的IEEE机器识别号,如果有网卡,从网卡mac地址获得,没有网卡以其他方式获得。

    ● UDN

    单一设备名(Unique Device Name),基于UUID,表示一个设备。在不同的时间,对于同一个设备此值应该是唯一的。

    ● URI

     Web上可用的每种资源 - HTML文档、图像、视频片段、程序等 - 由一个通用资源标志符(Universal Resource Identifier,简称"URI")进行定位。 URI一般由三部分组成:访问资源的命名机制;存放资源的主机名;资源自身的名称,由路径表示。考虑下面的URI,它表示了当前的HTML 4.0规范:http://www.webmonkey.com.cn/html/html40/它表示一个可通过HTTP协议访问的资源,位于主机www.webmonkey.com.cn上,通过路径“/html/html40”访问。

    ● URL

    URL是URI命名机制的一个子集,URL是Uniform Resource Location的缩写,译为“统一资源定位符”。通俗地说,URL是Internet上用来描述信息资源的字符串,主要用在各种www客户程序和服务器程序上。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。

    ● URN

    URN:URL的一种更新形式,统一资源名称(URN,Uniform Resource Name)。唯一标识一个实体的标识符,但是不能给出实体的位置。标识持久性Internet资源。URN可以提供一种机制,用于查找和检索定义特定命名空间的架构文件。尽管普通的URL可以提供类似的功能,但是在这方面,URN 更加强大并且更容易管理,因为 URN 可以引用多个 URL。

    -------------------------------------------------------------------------------------------------------

    关于UPnP组件

    完整的UPnP服务系统由支持UPnP的网络和符合UPnP规范的设备共同构成的。

    整个系统是由Device、Service、和Control Point三部分所构成。

    设备(Device):

    这里是指符合UPnP规范的设备。一个UPnP设备可以看成一个包含服务并嵌套了常规设备的“容器” 。例如,一个UPnP的VCR(录像机)设备可以包含磁带传送服务、调谐服务和时钟服务。就是说,UPnP之下的设备不能仅仅理解为硬件意义上的设备,而应当包括服务功能。

    不同种类的UPnP设备将关联不同的设置、服务和嵌入设备。如打印机和VCR属于不同用途的设备,服务就不可能定义成一样的。

    服务(Service):

    设备执行用户请求的控制过程,可划分成一个个很小的阶段或单位,每个单位就称为一个服务。每一个服务,对外都表现为具体的行为和模式,而行为和模式又可以用状态和变量值进行描述。只要可以用数值描述,在计算机里面就容易处理了。例如,模仿一个时钟,它只有一个工作模式:这个模式就是模拟并显示当前的时间。而一个时钟的行为共有两种(也只有两种):

    1. 设置时间(用来“即平时说的对表”).

    2. 得到时间(用于显示时间)。

    其它设备服务,也是用这样思路来描述和定义的,一个设备也可以被定义多个服务。不论是设备的定义信息和服务的描述信息,都保存在一个XML文件中,这个文件也是UPnP协议构成的一部分。当设备建立和使用服务的时候,XML文件可以与它们进行关联。

    XML文件中还有一个很关键的“状态表”,状态表可进一步分为“服务状态表”和“事件状态表”。整个UPnP设备运行的全过程内,状态表贯穿始终,当设备状态改变的时候,例如发生参数变化或状态刷新的时候,立即就在“状态表”中反映出来。如控制服务器在接收到设置时间的行为请求时,就立即执行请求(对时操作),并给出响应,同时更新状态表中的有关数据。相应地,事件服务器负责向对此事件感兴趣的设备公布所发生的状态改变。例如,一个火灾事件发生后,事件服务器就向火灾报警器发布这个事件,导致报警器动作产生报警信号。

    控制点(Control Point):

    在UPnP网络中,用户请求设备执行的控制是通过控制点实现的,控制点首先是一个有能力控制别的设备的控制者,还要具有在网络中 “发现”控制目标的能力。在发现(控制目标)之后,控制点应当:

    ①取得设备的描述信息并得到所关联的服务列表。

    ②取得相关服务的描述。

    ③调用控制服务行为。

    ④确定服务的事件 “源”,不论何时,只要服务状态发生改变,事件服务器会立即向控制点发送一个事件信息。

    从上面说到的各种信息,都保存在XML文件中,不同用途的信息,格式不同。保证可以各取所需,不会混淆。

    -------------------------------------------------------------------------------------------------------

     

    关于UPnP工作流程

     

    1、寻址(Addressing):

    地址是整个UPnP系统工作的基础条件,每个设备都应当是DHCP(Dynamic Host Configuration Protocol动态主机配置协议)的客户。当设备首次与网络建立连接后,利用DHCP服务,使设备得到一个IP地址。这个IP地址可以是DHCP系统指定的,也可以是由设备选择的,当然,有能力自己选择IP地址的设备,必然是那些“聪明”的设备才行!这也就是所谓的“自动”IP地址。

    如果遇到本地DHCP管理范围之外的IP地址请求,还需要解决“友好设备”的地址分配问题,这个问题通常由域名服务器来解决。

    2、发现(Discovery):

           可分成两种情况,一种是在有控制请求之后,在当前的网络中查找有无对应的可用设备;另一种情况是某一设备接入网络、取得IP地址之后,就开始向网络“广播”自己已经进入网络,即寻找控制请求。

           UPnP使用简单发现协议(SSDP)来完成发现,这是一个工作在UDP上的HTTP协议。

    当一个设备加入网络,它将向组播发送类似如下的消息:

    1. NOTIFY * HTTP/1.1  
    2. Host:239.255.255.250:1900  
    3. Cache-control:max-age=1800  
    4. Location:http://192.168.0.1:49152/des.xml  
    5. Nt:upnp:rootdevice  
    6. Nts:ssdp:alive  
    7. Usn:uuid:de5d6118-bfcb-918e-0000-00001eccef34::upnp:rootdevice  

    Host:这里必须使用IANA(InternetAssigned Numbers Authority)为SSDP预留的组播地址:239.255.255.250:1900。

    Cache-control:max-age的数值表明设备将在这段时间(单位为秒)后失效,因此,设备应当在失效前,重发这样的消息,标准指出,这里的数值应当不小于1800秒,但实际上,这里的取值范围取决于UPnP的实现。

    Location:设备描述文件的URL。

    Nt:Notification Type,这里的值upnp:rootdevice)表明这是一个“根设备”。每个设备可以有自己的子设备。

    Nts:Notification Sub Type,标准规定必须是ssdp:alive。

    Usn:Unique Service Name,是一个设备实例的标识符。

             通过这样的消息,控制点便可以知道网络中的设备。

             与之对应的是,当控制点加入网络时,它也将组播一个消息,用来发现设备:

    1. M-SEARCH* HTTP/1.1  
    2. Host:239.255.255.250:1900  
    3. Man:"ssdp:discover"  
    4. Mx:5  
    5. ST:ssdp:rootdevice  

    Host:同上。

    Man:必须是“ssdp:discover”。

    Mx:1到5之间的一个值,表示最大的等待应答的秒数。

    ST:Seatch Targer,表示搜索的节点类型。

    设备可以根据这样的搜索产生应答:

    1. HTTP/1.1200 OK  
    2. Cache-control:max-age=1800  
    3. Ext:  
    4. Location:http://192.168.0.1:2345/xx.xml  
    5. Server:Microsoft-Windows-NT/5.1UPnP/1.0 UPnP-Device-Host/1.0  
    6. ST:ST:urn:schemas-upnp-org:service:ContentDirectory:1  
    7. USN:uuid:60b2e186-b084-44af-ac09-1c64ea1bb364::urn:schemas-upnp-org:service:ContentDirectory:1  

    3、描述(Description):

    简单说,这是声明“自己”是什么样的设备,例如名称、制造厂商、序列号码等等。刚开始“发现”设备后,控制点对这个设备的“了解”还很少,需要依据ULR找到该设备的描述文件,从这些文件中读取更多的描述信息。描述信息的范围很广,一般都是由设备的制造厂商提供的。主要的描述项目有:控制的模式名称和模式号码、设备序列号、制造厂商名称、厂商的WEB的ULR等等。这些一般都存放在特定的XML文件中。

    设备的描述通过HTTP协议来完成。

    1. <?xmlversionxmlversion="1.0" encoding="utf-8"?>  
    2. <rootxmlnsrootxmlns="urn:schemas-upnp-org:device-1-0">  
    3.   <specVersion>  
    4.     <major>1</major>  
    5.     <minor>1</minor>  
    6.   </specVersion>  
    7.    
    8.   <device>  
    9.    <deviceType>urn:schemas-upnp-org:device:BinaryLight:1</deviceType>  
    10.     <friendlyName>KitchenLights</friendlyName>  
    11.    <manufacturer>OpenedHand</manufacturer>  
    12.     <modelName>VirtualLight</modelName>  
    13.    <UDN>uuid:cc93d8e6-6b8b-4f60-87ca-228c36b5b0e8</UDN>  
    14.    
    15.     <serviceList>  
    16.       <service>  
    17.        <serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>  
    18.        <serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>  
    19.        <SCPDURL>/SwitchPower1.xml</SCPDURL>  
    20.         <controlURL>/SwitchPower/Control</controlURL>  
    21.        <eventSubURL>/SwitchPower/Event</eventSubURL>  
    22.       </service>  
    23.     </serviceList>  
    24.   </device>  
    25. </root>  

    deviceType:设备类型,格式为:“urn:schemas-upnp-org:device:deviceType:v”,这里deviceType和v是由设备定义的。

    friendlyName:一个更加友好的设备名。

    Manufacturer:制造商。

    modeName:型号。

    UDN:Unique Device Name,设备的UUID。

    serviceList:服务列表。

    对于每一个服务:

    serviceType:与deviceType类似,这里的后两段由服务定义。

    serviceId:服务ID,通常于serviceType对应。

    SCPDURL:服务描述的URL。

    controlURL:用于控制的URL。

    eventSubURL:用于订阅事件的URL。

    一个服务描述的示例如下:

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <scpd xmlns="urn:schemas-upnp-org:service-1-0">  
    3.   <specVersion>  
    4.    <major>1</major>  
    5.    <minor>1</minor>  
    6.   </specVersion>  
    7.   <actionList>  
    8.     <action>  
    9.      <name>SetTarget</name>  
    10.       <argumentList>  
    11.         <argument>  
    12.           <name>NewTargetValue</name>  
    13.          <relatedStateVariable>Target</relatedStateVariable>  
    14.          <direction>in</direction>  
    15.         </argument>  
    16.       </argumentList>  
    17.     </action>  
    18.     <action>  
    19.      <name>GetTarget</name>  
    20.       <argumentList>  
    21.         <argument>  
    22.          <name>RetTargetValue</name>  
    23.          <relatedStateVariable>Target</relatedStateVariable>  
    24.          <direction>out</direction>  
    25.         </argument>  
    26.       </argumentList>  
    27.     </action>  
    28.     <action>  
    29.      <name>GetStatus</name>  
    30.       <argumentList>  
    31.         <argument>  
    32.          <name>ResultStatus</name>  
    33.          <relatedStateVariable>Status</relatedStateVariable>  
    34.          <direction>out</direction>  
    35.         </argument>  
    36.       </argumentList>  
    37.     </action>  
    38.   </actionList>  
    39.   <serviceStateTable>  
    40.     <stateVariablesendEventsstateVariablesendEvents="no">  
    41.      <name>Target</name>  
    42.      <dataType>boolean</dataType>  
    43.      <defaultValue>0</defaultValue>  
    44.     </stateVariable>  
    45.     <stateVariablesendEventsstateVariablesendEvents="yes">  
    46.      <name>Status</name>  
    47.      <dataType>boolean</dataType>  
    48.       <defaultValue>0</defaultValue>  
    49.     </stateVariable>  
    50.   </serviceStateTable>  
    51. </scpd>  

    actionList定义了“行为”,serviceStateTable定义了“状态变数”。

    每一个行为都由一个名称(name)和若干参数(argument)组成。二参数由名字(name)、传递方向(direction,取值in或者out)以及关联的状态变数(relatedStateVariable)组成。

    状态变数之所以叫做状态变数,是用来标明UPnP设备或程序的一些状态的。一个程序可以订阅(subscribe)状态的变化,从而得到通知。而一个参数之所以必须关联一个状态变数,是因为状态变数的类型决定了参数的类型。

    4、控制(Control):

    控制点找到设备描述之后,会从描述中“提炼”出要进行的操作并获悉所有的服务;对每个UPnP设备来说,这些描述必须是很确切、很详细的,描述中可能包含有命令或行为列表、服务响应信息、用到的参数等等。对于服务的每个行为,也伴有描述信息:主要是整个服务进行期间的变量、变量的数据类型、可用的取值范围和事件的特征。

    要控制某个设备,控制点必须先发送一个控制行为请求,要求设备开始服务,然后再按设备的ULR发送相应的控制消息,控制消息就是放置在XML文件中的那些SOAP格式的信息。最后,服务会返回响应信息,指出服务是成功或是失败。

    UPnP使用SOAP完成控制。SOAP工作在HTTP上,使用XML来描述远程调用并返回结果。

    1. POST /control/url HTTP/1.1  
    2. HOST: hostname:portNumber  
    3. CONTENT-TYPE: text/xml;charset="utf-8"  
    4. CONTENT-LENGTH: length ofbody  
    5. USER-AGENT: OS/versionUPnP/1.1 product/version  
    6. SOAPACTION:"urn:schemas-upnp-org:service:serviceType:v#actionName"  
    7.    
    8. <?xml version="1.0"?>  
    9. <s:Envelope  
    10.  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"  
    11.  s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">  
    12.     <s:Body>  
    13.         <u:actionNamexmlns:uu:actionNamexmlns:u="urn:schemas-upnp-org:service:serviceType:v">  
    14.            <argumentName>in arg value</argumentName>  
    15.         </u:actionName>  
    16.     </s:Body>  
    17. </s:Envelope>  

    actionName和argumentName就是在协议描述中定义的行为名称和参数名称。

    而调用的结果同样以XML方式返回:

    1. HTTP/1.1 200 OK  
    2. CONTENT-TYPE: text/xml;charset="utf-8"  
    3. DATE: when response wasgenerated  
    4. SERVER: OS/version UPnP/1.1product/version  
    5. CONTENT-LENGTH: bytes inbody  
    6.    
    7. <?xmlversionxmlversion="1.0"?>  
    8. <s:Envelope  
    9.  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"  
    10.  s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">  
    11.     <s:Body>  
    12.         <u:actionNameResponsexmlns:uu:actionNameResponsexmlns:u="urn:schemas-upnp-org:service:serviceType:v">  
    13.             <argumentName>out arg value</argumentName>  
    14.         </u:actionNameResponse>  
    15.     </s:Body>  
    16. </s:Envelope>  

    5、事件(Eveting):

    在服务进行的整个时间内,只要变量值发生了变化或者模式的状态发生了改变,就产生了一个事件,系统将修改上述提到的事件列表的内容。随之,事件服务器把事件向整个网络进行广播。另一方面,控制点也可以事先向事件服务器预约事件信息,保证将该控制点感兴趣的事件及时准确地传送过来。

    广播或预约事件,传送的都是事件消息,事件消息也放在XML文件中,使用的格式是GENA。设备投入工作之前的准备―――初始化过程,也是一个事件,初始化需要的各种信息也是用事件消息传送的。包括的内容主要是:变量初始值,模式的初始状态等等。

    订阅的URL事在服务描述中给出的。

    1. SUBSCRIBE publisher pathHTTP/1.1  
    2. HOST: publisherhost:publisher port  
    3. USER-AGENT: OS/versionUPnP/1.1 product/version  
    4. CALLBACK: <deliveryURL>  
    5. NT: upnp:event  

    此处,NT取upnp:event表示订阅事件;CALLBACK的值是回调的URL。

           与之对应的事订阅的应答:

    1. HTTP/1.1 200 OK  
    2. DATE: when response was generated  
    3. SERVER: OS/version UPnP/1.1 product/version  
    4. SID: uuid:subscription-UUID  
    5. CONTENT-LENGTH: 0  
    6. TIMEOUT: Second-1800  

    SID:本订阅的标识符,通常使用UUID。

    TIMETOUT:这里的值表示本订阅的有效期。这意味着在超时前,必须续订。

    续订的请求与订阅类似,只是附加了SID:

    1. SUBSCRIBE publisher path HTTP/1.1  
    2. HOST: publisher host:publisher port  
    3. SID: uuid:subscription UUID  
    4.    

    退订也类似:

    1. UNSUBSCRIBE publisher path HTTP/1.1  
    2. HOST: publisher host:publisher port  
    3. SID: uuid:subscription UUID  

    事件消息:

    1. NOTIFY delivery path HTTP/1.1  
    2. HOST: delivery host:delivery port  
    3. CONTENT-TYPE: text/xml; charset="utf-8"  
    4. NT: upnp:event  
    5. NTS: upnp:propchange  
    6. SID: uuid:subscription-UUID  
    7. SEQ: event key  
    8. CONTENT-LENGTH: bytes in body  
    9.    
    10. <?xml version="1.0"?>  
    11. <e:propertysetxmlns:ee:propertysetxmlns:e="urn:schemas-upnp-org:event-1-0">  
    12.     <e:property>  
    13.        <variableName>new value</variableName>  
    14.     </e:property>  
    15. </e:propertyset>  

     

    这里,每个产生事件的状态变数对应一个e:property标识,variableName是变数名。

    此外,SEQ是消息的顺序号,从0开始。

    当订阅者收到消息之后,必须在30秒内发送确认。

    HTTP/1.1 200 OK

    如果订阅者没有确认,设备仍然会发送之后的消息,直到本次订阅超时。

    6、展示(Presentation):

    只要得到了设备的ULR,就可以取得该设备表达页面的ULR,然后可以将此表达纳入用户的本地浏览器上。这部分还包括与用户对话的界面,以及与用户进行会话的处理。

    -------------------------------------------------------------------------------------------------------

     

    关于UPnP linux的体系结构

     

    1、  设备/控制点

    调用UPnP的标准API来实现设备和控制点的功能。

    2、  UPnP SDK

    UPnP软件开发包API部分将UPnP协议核的详细内容从控制点和服务器申请中抽象出来,并且给了一个统一界面的入口函数,里面包含了SSDP,GENA和SOAP等。

    3、  WEB server

    微型服务器模块处理一个标准的HTTP GET请求。在UPnP组成元素中,都要求使用基本的HTTP服务,所以需要使用微型服务器模块来完成基本的HTTP服务。微型服务器模块管理文档的定位,这些文档一般对GET命令有效,并且运行使用HTTP协议的数据流进行传输。

    微型服务器也支持虚拟路径HTTP POST请求,但不支持其他种类的请求。

    4、  XML解析器

    XML在UPnP中被广泛地使用。描述文档就是XML文档。GENA使用XML来描述一个服务状态的描述变化。SOAP使用XML来格式化请求和响应。软件开发包SDK包含一个XML解析,这个XML解析会被UPnP协议和客户端或服务端软件使用。

    5、  线程库

    UPnP协议栈的实现中大量采用了多线程技术,该模块就是为了更方便高校地使用线程技术,其中包含了一个定时器线程子模块和一个线程池子模块。线程池子模块用于管理协议栈中所有的线程;定时器线程子模块用来处理协议栈中所有的定时事件。

    应用层在调用API UpnpInit()时会初始化两个缓冲池:发送缓冲池和接收缓冲池。在创建每个缓冲池时都要给定一个缓冲池的属性作为参数,以确定在该缓冲池中最少,最多可以容纳的线程数,然后调用CreateWorker()创建所需的线程。

    当有新的任务要执行的时候,调用TPJobInit(),ThreadPoolAddPersistent()或者T火热阿迪PoolAdd()将任务加到缓冲池的相应队列中,等待空闲的线程调用执行。

    6、  HTTP解析器

    设备公告消息、设备查询消息、设备查询响应消息都是用HTTP协议来封装的,使用SSDP协议定义的头和方法,这需要开发者自己来解释这些消息。同样,事件订阅消息和事件取消订阅消息也是用HTTP协议来封装的,使用了GENA定义的头和方法,也需要开发者自己解析这些消息,这里把这两部分的HTTP消息解析合并为一个模块:HTTP消息的解析。通常的HTTP消息是由浏览器或者www服务器来解析的,这里的HTTP消息解析只对SSDP、GENA定义的特殊的HTTP消息进行解析。

    7、  微型服务器

    提供GENA、SOAP、SSDP、mini WEB server需要的公共功能,这一层接收所有的网络连接,并决定哪个请求可以进入上层,将HTTP头部交给HTTP模块去解析 ,并将这个连接转向合适的协议去处理。

    -----------------------------------------------------------
  • 相关阅读:
    结对-结对编项目贪吃蛇-最终程序
    团队-团队编程项目中国象棋-模块测试过程
    团队-团队编程项目中国象棋-模块开发过程
    团队-团队编程项目中国象棋-项目进度
    结对-结对编项目贪吃蛇-测试过程
    结对-贪吃蛇-开发过程
    课后作业-阅读任务-阅读提问-2
    20171005-构建之法:现代软件工程-阅读笔记
    结队-结队编程项目贪吃蛇-项目进度
    课后作业-阅读任务-任务阅读-2
  • 原文地址:https://www.cnblogs.com/cxt-janson/p/5102536.html
Copyright © 2011-2022 走看看