JasonWang's Blog

投屏中的服务发现协议

字数统计: 2.6k阅读时长: 9 min
2023/05/27

投屏是指将某个终端的音视频或者其他内容通过有线或者无线的形式投射到其他终端上的一种协议。目前常见的投屏协议有DLNA/Airplay/Mirracast/Chromecast:

  • DLNA(Digital Living Network Alliance): DNLA是由英特尔、索尼、微软等消费电子巨头在2003年建立的一个文件共享协议,目前很多的电视都会支持DLNA协议,用于手机与电视之间共享视频与图片等资源。
  • Airplay: Airplay是苹果公司开发的一个私有的投屏协议,实际包含了视频投屏与屏幕镜像等几个功能(音视频数据流包括交互控制协议都有是加密的),可以用于播放音频、视频,也可以把本地的图片投屏到电视上进行浏览。目前国内很多支持Airplay的投屏协议都是基于秘钥破解进行开发的。
  • Mirracast: MirracastWIFI联盟在2012年推出的一种基于WIFI将某个终端设备的音视频投屏到其他终端(比如电视、平板)上的协议,通常也被称为HDMI over WIFIAndroid最开始在AOSP 4.1上实现了一个类似的Mirracast协议,后来的版本则全部删除了,后来Google就推出了闭源的一个投屏协议Chromecast
  • Chromecast: Google在2013年基于Google Cast协议开发的一个闭源的投屏协议,可以用于播放在线的音视频内容,用户可以通过支持Google Cast协议的手机或PC上的浏览器来控制音视频内容的播放。同时,Google提供了一个SDK给第三方应用开发投屏功能。

对一个投屏协议来说,要在两个终端之间建立一个投屏的连接,通常需要经历如下几个步骤:

  • 被投屏的设备端以广播的形式向局域网的设备发布服务(该服务的信息通常会包含设备的名车,IP地址,以及通讯所用的端口地址等)
  • 需要投屏的终端发现该服务后,会基于广播中的端口地址与另一端建立网络链接(控制与数据传输可能需要分开两个连接)
  • 网络连接建立完成后,服务端需要告知对端设备的一些配置信息(比如设备的显示器的大小以及刷新率等)
  • 投屏完成初始化配置后,最后一步就是投屏的终端向服务端发送需要投屏的内容(内容可能是音视频数据流,也可能是一个在线播放的URL)

从上面的流程,我们可以看到,不同的投屏协议在其他方面可能有很大差别,但都离不开服务发现协议(Service Discovery)。在这篇文章,我们就来看看DLNA/Airplay/Mirracast三种投屏协议中所使用到的服务发现协议具体是怎么个原理。

DLNA的服务发现

DLNA中,播放音视频的一方通常被称为Digital Media Renderer(DMR),而发送音视频数据的一方则称为Digital Media Server(DMS), 负责中转数据的设备节点则称为Control Point(一般情况下,我们通常只有DMS/DMR两个设备,因此下文都是基于这种两个设备通讯的情况下进行讨论的)。DLNA使用UPnP(Universal Plug and Play)协议来进行服务发现以及数据的传输;UPnP可以在网络连接后通过UDP端口1900自动发布服务,DMS在收到该服务的广播消息后,会发送一个消息确认DMR的存在,这样整个服务发现过程就完成了。UPnP使用的服务发现协议叫做SSDP(Simple Service Discovery Protocol)

DMR服务启动后,会不断的通过组播地址239.255.255.250:1900发送Advertisement消息,广播系统当前的设备与服务状态(如果DMR中有多个设备或者服务,则会同时发送多个组播消息),告知DMS有相应的设备与服务可用; 需要投屏的设备(DMS)收到该广播消息后,主动发送一个M-SEARCH(ssdp:discover)的消息, DMR收到该消息后需要发送一个UDP消息给DMS设备,该消息需要包含一个与广播Advertisement中一样的UUIDAdvertisement消息一般有三种类型:

  • NOTIFY ssdp:alive: 当一个设备加入到网络中时需要发送alive消息广播根设备(root device)以及其他设备与服务的为可用状态,这样其他设备收到该消息后就可以发起连接
  • NOTIFY ssdp:byebye: 设备从网络中移除时需要发送一个byebyte的消息告知其他节点设备即将变为不可用状态
  • NOTIFY ssdp:update: 这个消息主要用于多IP设备广播设备与服务状态

alive组播消息为例,可以看到对于SSDP报文来说,最主要的字段主要有如下几个:

  • CACHE-CONTROL:max-age=1800: Advertisement消息最长生命周期
  • LOCATION: 根设备的URL地址,一般是由IP地址与连接协议的监听端口号组成
  • NT: 通知类型,如果是根设备通常是upnp:rootdevice, 其他设备对应的类型值是NT:uuid:<uuid>;如果是服务,则一般以urn开头,如:
    • NT: urn:schemas-upnp-org:device:MediaRenderer
    • NT: urn:schemas-upnp-org:service:ConnectionManager

SSDP服务广播报文结构

一旦完成服务发现,DMR通过SOAP/XML以及HTTP协议发布服务能力以及支持的协议,比如是否可以播放视频,是否能浏览图片等,最后通过连接服务来发送控制指令,可以完成诸如播放、暂停、跳转等功能。更多有关UPnP/SSDP协议相关的可以参考如下两个链接:

Airplay中的服务发现

苹果的Airplay协议算是投屏协议里比较完全全面的,可以支持在线的音视频投屏、屏幕镜像以及图片浏览等功能,而且投屏过程中加入了私有秘钥验证机制,可以说是这几个投屏协议里安全性最好的。另外,Airplay可以支持有线与无线两种投屏方式。

实际上Airplay包含了两个服务,一个用于传输音频数据流的RAOP(Remote Audio Output Protocol); 一个是用于传输视频与图片数据流的Airplay服务。Airplay中的服务发现是基于DNS的多播协议muticast DNS(mDNS)(最开始由Apple开源出来,也叫做Bonjour)来实现的,服务的发布与发现类似与域名的DNS解析过程:

  • 服务端通过mDNS服务进程发布RAOP/Airplay服务, 并监听UDP端口5353
  • 客户端连接上同一网络后,会发送QUERY到多播地址224.0.0.251对应的5353端口
  • 服务端的mDNS收到请求后,把登记好的服务发送给对应的客户端

通过单播(Unicast)方式发送的QUERY响应(RESPONSE)的消息,称为QU消息; 通过多播方式发送RESPONSE的消息,称为QM消息。这个标志位会在mDNS消息中设置

下面两个图分别是mDNSQUERY/RESPONSE的消息,可以看到mDNS的消息结构与DNS的完全一致: QUERY中包含了需要查询的服务以及权威名称服务(Authoritative nameservers, 实际是客户端网口的MAC组成的一个名字而已); RESPONSE消息(根据记录类型不同,一般有PTR/TXT两种)包含了服务的名称、协议类型,端口号以及协议所需要的其他字段(如设备的属性,设备的能力以及MAC地址等)。

mDNS query message

mDNS query response

完成服务发现后,客户端就会根据查询到的服务的端口与服务端建立连接,一般数据传输都使用TCP传输,其他的如时间同步协议则使用UDP

Android中已经集成了mDNS协议,代码可以参考mdnsresponder, 有关mDNS的详细细节可以参考RFC6762

Airplay是苹果公司的私有投屏协议,网上有一些相关的协议逆向分析的文档,但是都不算很全面,这里是之前搜索到的资料可以参考:

已有实现的参考代码Github RPiPlay

Mirrorcast中的服务发现

Mirrorcast在Android也被称作Wifi Display(WFD),简单来说是一个通过WIFI来传输音视频数据的协议, 可以用于设备的屏幕镜像,这个跟Airplay的屏幕镜像功能是类似的。早在Android 4.1的时候Google开源过相关代码; 从实现来看, Mirrorcast并不算复杂,其主要分为两个大的步骤:

  • 通过P2P协议(也叫做WIFI直连(Wifi Direct))发现可用的WFD设备
  • 与对应的P2P设备建立RTP连接,镜像的数据会通过RTP发送到接收端

P2P协议的发现分为两个流程,首先是设备的发现(Device Disconvery): 设备发现大致需要经过扫描与发现两个阶段。一个P2P设备要被发现需要处于LISTEN状态,并在2.4GHZ中的几个固定的Socical频段(1/6/11三个频段)选择一个频段进行监听,P2P设备在监听状态时只会对Prope Request Frames做出响应;设备在监听状态会等待固定的时间长度(0~100TU的随机时间)后,进入设备扫描阶段,扫描阶段,P2P会扫描周围设备与网络的所支持的所有频段。发现阶段的作用是确保两个设备处于同一个通讯频段。

P2P device discovery process

设备发现完成后,就会进行服务发现。P2P的服务协议可以基于Airplay/DLNA中的协议如mDNS/UPnP进行扩展。搜索的一端主动发送Service Discovery数据帧,服务端收到搜索请求后发送Response给对端。Android S中可以看到两种服务发现协议的封装WIFI P2P NSD

P2P service discovery process

有关WIFI P2P的更多细节可以参考标准文档WIFI Direct Spec; 相关的代码实现可以参考AOSP的源码:

参考资料

原文作者:Jason Wang

更新日期:2023-07-07, 09:40:37

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

CATALOG
  1. 1. DLNA的服务发现
  2. 2. Airplay中的服务发现
  3. 3. Mirrorcast中的服务发现
  4. 4. 参考资料