智能互联开发标准文档
智能互联开发标准文档

概述

为了实现在基于IP协议的局域网内部,不同厂商的智能设备之间互相通信、互相操作,我们梳理了这份智能互联开放标准(局域网),本文简要描述了智能设备从接入局域网到与其他设备完整互操作的整个生命周期里所涉及的通信方式,和所使用到的协议和技术。具体技术细节,每一个部分的具体技术细节会另由独立章节进行详细阐述。

如果有任何问题或建议,请联系dev-support@mochui.net

基本功能

本开放标准从四个方面定义了智能设备互联的通信方式:局域网接入、在网络里的注册和发现、授权认证和服务调用。任何设备通过这四个阶段通信方式的标准化,将可以和其他设备实现完全的互操作,并且保证了用户端的易用性,用户数据的安全性,网络的可扩展性。

局域网

本开放标准适用于基于IP协议的局域网内部的智能设备。局域网必须基于IP协议,开放标准里使用到多种基于IP协议的上层协议,如TCP,DNS,UDP等。

跨不同局域网或非IP协议网络的设备之间的互通操作不在本开放标准讨论范围里。

局域网接入

基于IP协议的局域网接入的方式目前有以太网和WiFi。

局域网接入对于以太网设备只需要简单地插上网线。

对于WiFi设备,可以使用标准WPS按键模式(Wi-Fi Protected Setup Push-Button-Method)以及类Smartconfig两种方式接入。

WPS是WiFi协议所规定的标准接入方式。使用时需要用户到路由器上按一下WPS按钮打开WPS功能,再按一下新接入设备上的WPS按钮完成配对。本开放标准下,路由器提供软件WPS开启API,当用户所使用的APP在路由器上认证通过后,用户使用该APP添加新设备时,不再需要在路由器上按WPS开关。APP可以自动通过路由器上的API短时间打开路由器的WPS功能,WPS在2分钟内或设备连接成功后自动关闭:

GET /wps

类SmartConfig是WiFi芯片或模块厂商所研发的一种连接协议,各种实现方式略有不同,但本质上是把路由器的WiFi名称和密码通过非WiFi的方式传递给新接入设备。用户使用时,需要在手机APP里输入当前wifi密码,并按下连接按钮,等待新设备获得WiFi名称和密码并完成接入。本开放标准下的路由器也对这种方式提供了优化支持。路由器提供获得WiFi名称和密码的API接口,当用户所使用的APP在路由器上认证过后,用户通过类SmartConfig添加新设备时,不再需要输入wifi密码,用户APP可以通过路由器提供的API自动获得路由器密码,并发送给新设备:

GET /wifi_passwd

注册、发现服务

在设备接入网络之后,需要把自己所提供的服务在网络内注册公布,并查询网络内现有的服务。在注册和发现服务功能上,我们使用一套零配置网络(zero-configuration networking)协议。这套协议最广泛应用,最成熟的实现是Apple的Bonjour,我们用Bonjour的开源版本Avahi来完成局域网内部服务的发现和注册功能。

Bonjour

Bonjour是苹果实现的零配置网络协议。此协议的设计宗旨是希望简化用户在使用局域网络时的配置操作。举一个例子,Bonjour可以让一台电脑方便得连上局域网内的打印机,电脑原先不知道打印机的IP地址,也不需要用户手动在计算机上输入打印机的IP地址。使用这套零配置协议,附近的电脑都可以自动发现这台打印机,并且自动连接上。即使这台打印机的IP地址会动态改变,附近的电脑也能自动发现新IP并自动连接上。

这样一套协议非常适合于局域网内部智能设备的注册和发现服务上。

服务

和其他网络协议不同,Bonjour设计上的核心对象是“服务(Service)”,而不是设备(Device)。对于最终用户来说,用户关心的是网络里可用的服务,而不是设备。一个设备可能提供一个或多个服务。一个服务也可能因为设备问题(损坏,更新硬件等),被迁移到不同的设备上。所以从用户使用的角度来说,最简单的情况是,用户只需问“网络里提供哪些服务?” 这样一个简单地问题来得到当前网络里所有的服务,然后用户针对感兴趣的服务询问详细信息和调用方式。

DNS

Bonjour的两个核心模块是mDNS(multicast DNS)和DNS-SD(DNS Service Discovery)。这两个模块都是以DNS(Domain Name System)协议为基础发展而来。这里先简单介绍一下会用到的DNS相关知识。

DNS是一套层级式、分布式网络设备命名系统,可以用在互联网或局域网中。它本质上是把人们容易记住的名字翻译成IP地址,使得上层应用方便得建立IP层面的连接。形象得说,DNS类似一个电话本系统,把人名和电话号码对应起来。一个人可能有多个电话号码,也可能换新号码。但只要记住这个人的名字,就可以查到其电话号码,并联络到他。

DNS系统对每一个域名所记录下的不仅仅是IP地址,而是包含了多条记录(DNS Record)。记录分为不同类型,代表不同的信息。这里介绍几条我们会较常用到的记录类型

记录类型 全名 描述
A Address Record 记录了本域名的IP地址,IPv4。
PTR Pointer Record 指向一个另一个域名。这条记录里地内容常会被其他协议用在不同的地方,比如DNS-SD里。
SRV Service locator 通用的服务记录,用于记录本域名下提供的服务名称,一个域名下可以有多条SRV记录。专门用来给基于DNS扩展的协议使用。
TXT Text Record 附录字段,用于放置附加描述信息的字段,可以是供人读取,也可以是供机器读取。


在查询一个域名的信息时,可以指定查询这里任何一个类型里的记录信息。

比如我们在局域网内通过命令行查询modouwifi.net的A记录如下所示:

$ nslookup
> set type=A
> modouwifi.net
Server:   192.168.18.1
Address:  192.168.18.1#53

Name: modouwifi.net
Address: 192.168.18.1

modouwifi.net其实是魔豆路由器在局域网内的域名,所以解析出来的结果就是网关192.168.18.1。在命令行查询modouwifi.net的TXT记录如下所示:

$ nslookup
> set type=TXT
> modouwifi.net
Server:   192.168.18.1
Address:  192.168.18.1#53

modouwifi.net text = "hello hd!"

注册服务

Bonjour里的mDNS(multicast DNS)模块主要完成服务的注册功能。

注册过程是一个新设备接入网络以后,给设备自身和设备所提供的服务命名,并发布的过程。mDNS把DNS格式的信息通过IP multicast向当前局域网里所有的设备发出查询,使用这样的查询和回应的方式来完成注册。

在mDNS协议里,每一个设备有一个迷你DNS服务器,mDNSResponder(Multicast DNS responder)。他们只解析自己的域名,对于其他设备的域名的查询完全不予回应。通过这样的机制,一个设备在局域网内获得域名的步骤是:

  1. 首先设备向整个网络发出自己希望使用的域名的DNS解析查询(比如plug.local),如果网络里有任何对这条查询的回应,说明此域名已经被占用
  2. 根据预先设定的规则,更改希望使用的域名(plug-1.localplug-2.local等),再次查询网络里是否存在该域名
  3. 直到找到一个没有被使用的域名,就把该域名认为是自己的域名(plug-3.local)。

在设备域名获得以后,服务的注册是通过设备本地的mDNSResponder完成的。上层软件把服务的名称等其他信息交给mDNSresponder,mDNSResponder将在本地的DNS记录中添加SRV(服务名),PTR(服务类型)和TXT(附加信息)3条记录以供其他设备查询。在完成本地信息配置后,mDNSResponder会在网络内部发布新服务的信息,使得网络内所有设备得知新服务开启。

如果软件提供的服务名已经在本域内出现过,则用类似的域名获得的规则自动更改成本域上没有使用过的服务名。

发现服务

Bonjour的最后一部分是服务发现模块,DNS-SD(DNS Service Discovery)。DNS-SD允许用户查看网络里存在的服务类型,并根据服务类型查询网络里现有的所有服务。通过记录服务的名称,用户不需要记录每一个服务的IP。当网络内IP由于任何原因产生变动,只要服务名称不变,用户仍然可以无缝使用服务。

dns-sd是Mac端的命令行程序,这里使用该命令行程序演示一下Mac下Bonjour的服务发现过程。

列出当前局域网里所有的服务类型:

$ dns-sd -B _services._dns-sd._udp

Browsing for _services._dns-sd._udp
DATE: ---Mon 16 Jun 2014---
18:32:39.300  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
18:32:39.564  Add        3   5 .                    _tcp.local.          _home-sharing
18:32:39.564  Add        3   5 .                    _tcp.local.          _pastebot-c2
18:32:39.564  Add        3   5 .                    _tcp.local.          _device-info
18:32:39.564  Add        2   5 .                    _tcp.local.          _afpovertcp
18:32:39.570  Add        3   5 .                    _tcp.local.          _ssh
18:32:39.570  Add        2   5 .                    _tcp.local.          _sftp-ssh

我们从这个列表里可以看到,所有的服务都是TCP协议上的,一共有6种不同的TCP服务。我们看一下home-sharing类型的服务具体有哪些:

$ dns-sd -B _home-sharing._tcp

Browsing for _home-sharing._tcp
DATE: ---Mon 16 Jun 2014---
18:33:51.665  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
18:33:51.930  Add        2   5 local.               _home-sharing._tcp.  Forrest Ye’s Library

这里我们列出了所有home-sharing类型的服务,从列出的结果可以看到,局域网内只有一个这样的服务,服务名称为Forrest Ye’s Library。我们再来看一下Forrest Ye’s Library服务的具体详细信息。

$ dns-sd -L "Forrest Ye’s Library" _home-sharing._tcp

Lookup Forrest Ye’s Library._home-sharing._tcp.local
DATE: ---Mon 16 Jun 2014---
18:35:11.730  ...STARTING...
18:35:11.731  Forrest\032Ye’s\032Library._home-sharing._tcp.local. can be reached at fairy-2.local.:3689 (interface 5)
 txtvers=1 dmv=131082 hQ=2362 MID=0x9C43B7DCA8E12470 Version=196620 iTSh\ Version=196618 PrVs=65538 DvSv=2850 DvTy=iTunes Machine\ Name=Forrest\ Ye’s\ Library OSsi=0x1F5 iCSV=65539 hG=00000000-40fa-fd9e-7ef7-b10e8c2c468c Database\ ID=816071BD38F5BABF Machine\ ID=00E39BBFDF2D hC=cc2933d3-5925-4c5c-9b02-efd03b988c32

从结果可以看到,该服务在域名fairy-2.local,端口号3689上提供服务。我们即可以通过该地址和端口访问此服务。

这是一个Bonjour在计算机端的演示,一样的过程可以在任何一个支持DNS-SD的终端设备上进行,方便地发现局域网内提供的服务,并得到任何服务的信息。

减少网络通信

Bonjour是一个无中心的网络,在这样的网络里注册服务,发现服务的行为如果处理不当可能产生较大的网络流量。Bonjour使用了一些方式来把网络流量降到最低,包括缓存、避免重复回复、延迟发送和服务公布3种优化方式。

缓存:Bonjour把收到的mDNS记录存在缓存中,来避免设备重复询问已经被询问过的问题。例如,当局域网中一个设备查询了当前网络里所有的打印机,因为回复信息也是以mDNS方式发送给网络里所有设备,其他设备也会收到所有打印机的信息。在这些信息没有过期前,同一网络里的其他设备不需要再查询打印机列表。

避免重复回复:为了避免对于类似问题的重复回答,Bonjour的mDNS查询包里会包含已知的回答。例如,如果网络中一台设备正在查询网络里所有的打印机。第一条查询得到3个打印机的回复。下次再有设备查询打印机时,就可带着已知的3台打印机在查询包里,这样这些已被网络里其他设备所知的打印机就不需要回复,只有这3个打印机以外的新打印机才需要回复。

延迟发送和服务公布:当一台在网络里的设备需要持续发现网路里地新服务时,设备并不需要持续不断地发送服务发现的查询。设备在第一次发送查询以后,之后的查询都将以指数级增加的时间间隔延迟发送。比如后续的发送时间间隔为1秒,3秒,9秒,27秒等。一直到最长时间间隔1小时。

这并不意味着新服务开启后1个小时才会被发现。当一个新服务在网络里开启之后,它将使用和上面类似的延迟发送机制在网络里宣布自己的存在。通过这种方式,整个网络的流量在保持在最小的情况下,新服务的开启也将被最快速得发现。

服务调用

近二,三十年互联网的成功有目共睹,互联网得以快速大范围传播的重要原因之一,是不同地方,不同人建起的网站,都可以使用一个通用协议HTTP实现互相链接,互相调用资源。物联网想要得到想互联网一样的发展,也必须有这样一个通用协议,任何人制作出的智能设备都可以方便得连接和调用现有其他设备上的资源。

国际互联网工程任务组

国际互联网工程任务组”(The Internet Engineering Task Force,简称 IETF)是国际互联网业界权威的网络相关技术研究团体,其主要任务是负责互联网相关技术标准的研发和制定。

由于物联网设备由于计算能力和存储资源的限制并不适合直接使用HTTP协议,IETF特别成立工作组CoRE(Constrained RESTful environments),专门制定在资源受限设备上网络通信协议。

CoAP

CoRE工作组近期完成的了CoAP(Constrained Application Protocol)通信协议的定制,参见RFC7252。CoAP是一种简单电子设备通过网络进行通信的网络通信协议,特别适合于小型传感器设备、无线开关等需要通过标准通信接口进行远程控制、通信的设备。CoAP提供一套类HTTP的请求/回应通信模型,内建资源发现机制,包含了一些HTTP的经典要素如URI,content-type等。CoAP的请求被设计成非常容易翻译成HTTP请求,从而极易和web服务做整合,同时协议有对于物联网设备非常重要的组播(Multicast),设计简单,基于UDP等特点。

CoAP特性:

基于UDP

CoAP是一个基于UDP的7层通信协议。使用UDP而不是TCP可以最大程度减少对设备资源的消耗。但是UDP不保证信息绝对传递的特点,需要在消息模型层面得以解决

              +----------------------+
              |      Application     |
              +----------------------+
              +----------------------+  \
              |  Requests/Responses  |  |
              |----------------------|  | CoAP
              |       Messages       |  |
              +----------------------+  /
              +----------------------+
              |          UDP         |
              +----------------------+

消息模型

CoAP的消息分为需确认消息(Confirmable Message),不需确认消息(Non-confirmable Message)和回应消息(Acknowledgement Message)。

授权认证

正在梳理中。