WFD_RTSP交互包分析
在WFD交互过程中,在Source端或者Sink端抓取tcpdump,通过数据包分析软件Wireshark或者Omnipeek即可以直观的分析RTSP协议交互的过程。
目录
- 0.准备
- 1.抓包
- 2.包过滤
- 3.包分析
- 3.1 RTSP M1 Message
- M1 Request
- M1 Response
- 3.2 RTSP M2 Message
- M2 Request
- M2 Response
- 3.3 RTSP M3 Message
- M3 Request
- M3 Response
- 3.4 RTSP M4 Message
- M4 Request
- M4 Response
- 3.5 RTSP M5 Message
- M5 Request
- M5 Response
- 3.6 RTSP M6 Message
- M6 Request
- M6 Response
- 3.7 RTSP M7 Message
- M7 Request
- M7 Response
- 3.1 RTSP M1 Message
关于WFD协议和代码追踪请参考阅读: Wi-Fi Display协议介绍 WFD连接过程代码分析(Sink端)
0.准备
本次分析过程在Sink端抓取tcpdump,通过Wireshark软件分析RTSP交互M1~M7消息交互
- Source端设备->Android Phone
- Sink端设备->Android TV
- Wireshark包分析软件
1.抓包
在Source端抓取tcpdump
adb shell
tcpdump -i any -s 0 -w /data/vendor/wifi/file.pcap
adb pull /data/vendor/wifi/file.pcap ./
//注: //-i any 表示抓取所有接口(waln0、p2p0等) //data/vendor/wifi/file.pcap 为设备端存储的路径
2.包过滤
使用Wireshark打开file.pcap,在Filter(过滤器)输入过滤条件
ip.addr==192.168.49.1 and rtsp
//注: //ip.addr==192.168.49.1 为WiFi P2P连接GO(Group Owner)的IP地址,此处搜索GC(Group Client)的IP地址192.168.49.141也可以 //rtsp 为协议类型
3.包分析
下列图中
- Source端IP地址为192.168.49.1(承担P2P GO角色)
- Sink端IP地址为192.168.49.141(承担P2P GC角色)
3.1 RTSP M1 Message
WFD RTSP交互开始于WFD Source端发送M1,M1 Message属于固定交互模式,Source端发送Request给Sink端,Sink端收到后回复Response。
M1 Request
如下图所示,Source发送给Sink在消息体里面包含
- Request: OPTIONS * RTSP/1.0rn 用于标记此条消息的用途是询问对方options
- CSeq:1rn 由发送者分配,用于计数(标记)Source端发送的Request消息
- Server: AllShareCast/Galaxy/3.2/NIBCrn
- Require: org.wfa.wfd1.0rn 作为tag,用于询问对方支持的WFD options
注:WFD协议规定每一个字段都以“rn”结尾
M1 Response
如下图所示,Sink发送给Source在消息体里面包含
- Response: RTSP/1.0 200 OKrn 状态码200用于接收成功
- Date: Tue, 19 Nov 2019 12:35:04 +0000rn 时间信息
- User-Agent: stagefright/1.1 (Linux;Android 4.1)rn
- CSeq: 1rn 回复Request发送过来的CSeq值,用于标明是对CSeq=1这条消息的回复
- Public: org.wfa.wfd1.0, GET_PARAMETER, SET_PARAMETERrn 协议中标明Sink端在接收到Source端Request消息后固定的答复内容
3.2 RTSP M2 Message
当M1交互完成后,开始M2交互,也属于固定交互模式,Sink端发送Request给Source端,Source端收到后回复Response
M2 Request
如下图所示,Sink发送给Source在消息体里面包含
- Request: OPTIONS * RTSP/1.0rn 用于标记此条消息的用途是询问对方options
- Date: Tue, 19 Nov 2019 12:35:04 +0000rn 时间信息
- User-Agent: stagefright/1.1 (Linux;Android 4.1)rn
- CSeq: 1rn 由发送者分配,用于计数(标记)Sink端发送的Request消息
- Require: org.wfa.wfd1.0rn 作为tag,用于询问对方支持的WFD options
M2 Response
如下图所示,Source发送给Sink在消息体里面包含
- Respose: RTSP/1.0 200 OKrn 状态码200用于接收成功
- CSeq: 1rn 回复Request发送过来的CSeq值,用于标明是对CSeq=1这条消息的回复
- Public: org.wfa.wfd1.0, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETERrn 协议中标明Source端在接收到Sink端Request消息后固定的答复内容
3.3 RTSP M3 Message
M1和M2交互类似日常见面的打招呼,你Hi一句,我点个头回复一句Hello。接下来进行的M3交互,询问Sink端的能力和支持的功能。
M3 Request
如下图所示,Source发送给Sink在消息体里面包含
- Request: GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0rn 用于标明获取Sink端的参数
- CSeq: 2rn 用于标注Source发出的第二条Request
- Content-type: text/parameters 用于标明消息体中包含parameters
- Content-length: 338 表示parameters长度
- Line-based text data: text/parameters (15 lines) 下面列出具体的参数
- wfd_video_formatsrn 视频格式
- wfd_audio_codecsrn 音频格式
- … …
M3 Response
如下图所示,Sink发送给Source在消息体里面包含
- Response: RTSP/1.0 200 OKrn 状态码200用于接收成功
- Date: Tue, 19 Nov 2019 12:35:04 +0000rn 时间信息
- User-Agent: stagefright/1.1 (Linux;Android 4.1)rn
- CSeq: 2rn 回复Request发送过来的CSeq值,用于标明是对CSeq=2这条消息的回复
- Content-type: text/parameters
- Content-length: 327
- Line-based text data: text/parameters (8 lines)
- wfd_video_formats: 48 00 02 02 0001DEFF 157C7FFF 00000FFF 00 0000 0000 00 none nonern 视频编码格式
- wfd_audio_codecs: LPCM 00000003 00rn 音频编码格式
- wfd_content_protection: nonern 不支持HDCP加密
- wfd_coupled_sink: 00 nonern 不支持有主Sink和次Sink耦合
- wfd_uibc_capability: nonern 不支持UIBC
- wfd_standby_resume_capability: nonern 不支持standby
- wfd_lg_dlna_uuid: nonern
- wfd_client_rtp_ports: RTP/AVP/UDP;unicast 15550 0 mode=playrn Sink端RTP交互端口为15550
3.4 RTSP M4 Message
M3交互Source端了解到Sink端的编解码能力后,Source依据自身的能力和Sink端的能力决定使用编解码格式等,通过M4发送给Sink端,Sink端如果验证后支持,则回复ok,如不支持,则M3继续协商。
M4 Request
如下图所示,Source发送给Sink在消息体里面包含
- Request: SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0rn 用于设置使用的音视频格式等
- CSeq: 3rn 用于标注Source发出的第三条Request
- Content-type: text/parameters
- Content-length: 248
- Line-based text data: text/parameters (4 lines)
- wfd_video_formats: 00 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none nonern 使用这个视频格式
- wfd_audio_codecs: LPCM 00000002 00rn 使用这个音频格式
- wfd_presentation_URL: rtsp://192.168.49.1/wfd1.0/streamid=0 nonern 用于设置WFD会话
- wfd_client_rtp_ports: RTP/AVP/UDP;unicast 15550 0 mode=playrn
M4 Response
如下图所示,Sink发送给Source在消息体里面包含
- Response: RTSP/1.0 200 OKrn 状态码200用于接收成功
- Date: Tue, 19 Nov 2019 12:35:04 +0000rn
- User-Agent: stagefright/1.1 (Linux;Android 4.1)rn
- CSeq: 3rn 回复Request发送过来的CSeq值,用于标明是对CSeq=3这条消息的回复
3.5 RTSP M5 Message
M4交互完毕后,开始建立WFD会话,即M5的交互
M5 Request
如下图所示,Source发送给Sink在消息体里面包含
- Request: SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0rn
- CSeq: 4rn 用于标注Source发出的第四条Request
- Content-type: text/parameters
- Content-length: 27
- Line-based text data: text/parameters (1 lines)
- wfd_trigger_method: SETUPrn 开始WFD会话建立
M5 Response
如下图所示,Sink发送给Source在消息体里面包含
- Response: RTSP/1.0 200 OKrn 状态码200用于接收成功
- Date: Tue, 19 Nov 2019 12:35:04 +0000rn 时间信息
- User-Agent: stagefright/1.1 (Linux;Android 4.1)rn
- CSeq: 4rn 回复Request发送过来的CSeq值,用于标明是对CSeq=4这条消息的回复
3.6 RTSP M6 Message
M5后,Sink端给Source端发送M6 Request
M6 Request
如下图所示,Sink发送给Source在消息体里面包含
- Request: SETUP rtsp://192.168.49.1/wfd1.0/streamid=0 RTSP/1.0rn
- Date: Tue, 19 Nov 2019 12:35:04 +0000rn 时间信息
- User-Agent: stagefright/1.1 (Linux;Android 4.1)rn
- CSeq: 2rn 用于标注Sink发出的第二条Request
- Transport: RTP/AVP/UDP;unicast;client_port=15550-15551 Sink端RTP交互端口为15550,RTCP交互端口为15551
M6 Response
如下图所示,Source发送给Sink在消息体里面包含
- Response: RTSP/1.0 200 OKrn 状态码200用于接收成功
- CSeq: 2rn 回复Request发送过来的CSeq值,用于标明是对CSeq=2这条消息的回复
- Session: 1957747793;timeout=30 标明会话ID为1957747793和超时
- Transport: RTP/AVP/UDP;unicast;client_port=15550-15551;server_port=19000-19001 //重述Client(Sink)端的端口,并标明Source(Server)RTP交互端口为19000,RTCP交互端口为19001
3.7 RTSP M7 Message
M6交互完毕后,M7告知Source端一切准备就绪,开始发送数据
M7 Request
如下图所示,Sink发送给Source在消息体里面包含
- Request: PLAY rtsp://192.168.49.1/wfd1.0/streamid=0 RTSP/1.0rn
- Date: Tue, 19 Nov 2019 12:35:06 +0000rn
- User-Agent: stagefright/1.1 (Linux;Android 4.1)rn
- CSeq: 3rn 用于标注Sink发出的第三条Request
- Session: 1957747793
M7 Response
如下图所示,Source发送给Sink在消息体里面包含
- Response: RTSP/1.0 200 OKrn 状态码200用于接收成功
- CSeq: 3rn 回复Request发送过来的CSeq值,用于标明是对CSeq=3这条消息的回复
- Session: 1957747793;timeout=30
- Range: npt=now-rn
综上所述
Message |
Method |
Direct |
简述 |
重点 |
---|---|---|---|---|
M1 |
OPTIONS |
Source -> Sink |
打招呼 |
|
M2 |
OPTIONS |
Source <- Sink |
打招呼 |
|
M3 |
GET_PARAMETER |
Source -> Sink |
你支持什么音视频格式 |
wfd_video_formats/wfd_audio_codecs |
M4 |
SET_PARAMETER |
Source -> Sink |
我们使用这个格式吧 |
|
M5 |
SETUP |
Source -> Sink |
建立连接吧 |
|
M6 |
SETUP |
Source <- Sink |
建立连接吧 |
client_port/server_port/Session ID |
M7 |
PLAY |
Source <- Sink |
开始发送数据吧 |
在M1-M7交互完毕,开始传输音视频数据过程中,由于一些外部原因(信号强弱)或者内部原因双方会动态调整使用的音视频格式,所以还有可能会交互GET_PARAMETER如下图所示,这里不再敖述。
参考: 【1】《Wi-Fi_Display_Technical_Specification_v2.1_0》
- Go语言cmd命令通过管道实现交互
- 三撩Python
- linq学习笔记(二)
- 盘点2017十大科学突破,让孩子与未来相遇
- ASP.NET 2.0 中的异步页[来自MSDN]
- 温习sql语句中JOIN的各种操作(SQL2005环境)
- 揭开ps的神秘面纱——初步认识photoshop
- 地理坐标系与投影坐标系的区别
- ExtJs学习笔记(6)_可分页的GridPanel
- PowerDesinger联系的定义及使用
- Gis链接
- TortoiseSVN文件夹及文件图标不显示解决方法 TortoiseSVN文件夹及文件图标不显示解决方法
- 地图坐标
- PowerDesigner15连接Oracle失败的解决办法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 干货 | 滴滴 数据分析原来是这样做的!
- 数据链路层之PPP协议
- matplotlib基础绘图命令之boxplot
- MapReduce之GroupingComparator分组(辅助排序、二次排序)
- MySQL优化--概述以及索引优化分析
- MySQL优化--查询分析工具以及各种锁
- MySQL优化--MVCC
- Linux入门--基础命令
- Linux入门--权限管理、任务调度、磁盘管理
- 【Rust日报】2020-08-05 -- 如何在2020年进一步加快 Rust 编译器的速度
- Linux学习--网络、进程、服务、软件管理
- IOS label 设置行高
- 重学数据结构(序:概览)
- 【Rust日报】2020-08-06 使用 Rust 编写的 Lambdas 在 AWS IoT 和 SQS 队列之间传递消息
- react-router-config的使用