飞利浦摄像头网络协议分析
本文整理飞利浦品牌、云看看 App、FH8626V100 平台摄像头的 UDP 云协议。基于抓包分析并已在本地模拟服务器中验证云台、语音对讲、夜视、重启和移动跟踪。
本文只把抓包能够证明的行为写成结论。未确认的字段、跨型号兼容性和安全语义均明确列在文末,不能把本文视为厂商正式协议规范。
1. 协议总览
摄像头不会固定连接某一台媒体服务器。它先访问多个引导节点,再由引导节点下发动态会话 IP、UDP 端口和 4 字节令牌。摄像头每次启动或重新会合时,本地端口和远端节点都可能变化,因此实现中不能写死最终 UDP 五元组。
一个完整会话分为五层:
1 | DNS/路由接管 |
已识别的逻辑通道:
| 通道 | 方向 | 用途 |
|---|---|---|
D1 00 |
双向 | 会话初始化、能力交换、云台及设备功能控制 |
D1 01 |
服务器 → 摄像头 | G.711 A-law 语音对讲 |
D1 02 |
摄像头 → 服务器 | H.264 视频/媒体数据 |
D1 03 |
摄像头 → 服务器 | H.264 视频/媒体数据 |
所有多字节字段并非统一字节序:外层长度、可靠序号和 ACK 序号使用大端;地址、端口、控制命令、控制数据长度及多数命令数据使用小端。实现时应逐字段处理。
2. 引导与会合
2.1 DNS 与引导节点
抓包中摄像头向硬编码 DNS 114.114.114.114 查询:
p2p2.cloudbirds.cnp2p3.cloudbirds.cn
摄像头还会访问未必由这两次 DNS 查询返回的备用节点,并向公网 UDP32100–32102 发送引导报文。因此,仅劫持域名不足以保证离线运行;网关还需接管摄像头的 UDP/53,以及它发往公网 UDP 32100–32102 的流量。
2.2 F1 00 / F1 01:NAT 映射探测
摄像头发送:
1 | F1 00 00 00 |
引导节点回复 20 字节:
1 | offset size endian 含义 |
2.3 F1 12 / F1 13:设备注册
F1 12总长 48 字节,长度字段为0x002C。- 同一 UDP socket 发给多个引导节点的内容相同;切换 socket 后,末尾约 16 字节会变化。
F1 13总长 12 字节,是注册确认。F1 12内部可能包含时间、随机数、签名或设备认证信息,目前尚未解出。本地模拟服务器只把它视为不透明请求并按抓包格式回应。
2.4 F1 40 / F1 41:候选地址和打洞
F1 40 是 20 字节候选地址,端口和 IPv4 的位置、字节序与 F1 01 相同。摄像头随后向公网及私网候选端口发送携带明文设备 ID 的 F1 41。这一阶段用于直连候选打洞,不是最终控制或视频通道。
2.5 F1 82 / F1 83:下发会话节点
F1 82 总长 24 字节:
1 | offset size endian 含义 |
摄像头向该地址发送 32 字节 F1 83:
1 | F1 83 | 00 1C | token[4] | device_id[20] | flag_le32 |
摄像头首次报到时 flag=1。最终节点依次返回:
F1 03 00 00;- 携带设备 ID 的
F1 84; - 相同 token 和 device ID、但
flag=0的反向F1 83。
本地服务端应保存 F1 83 的实际来源 IP 和端口,并把它作为本次会话对端。设备重启或重新会合后必须重新学习,不能沿用旧端口。
3. 会话可靠层
3.1 数据包 F1 D0
1 | offset size endian 含义 |
各逻辑通道独立使用序号。相同通道、相同序号再次出现表示重传,接收端应再次 ACK,但不得重复执行云台、重启等有副作用的命令。
3.2 选择确认 F1 D1
1 | offset size endian 含义 |
确认 D1 00 序号 2 的示例:
1 | F1 D1 00 06 D1 00 00 01 00 02 |
ACK 中的序号是集合,不是连续范围。控制通道通常逐包确认,视频和音频可以批量确认。发送端超时重试时应重发原序号,不应为同一次操作分配新序号。
4. D1 00 控制记录
F1 D0 / D1 00 的 offset 8 之后可以连续放置一条或多条控制记录:
1 | offset size endian 含义 |
已观察到的初始化和能力记录:
| 请求 | 响应 | 已确认信息 |
|---|---|---|
0x0010 |
0x0010 |
会话问候/认证交换;服务器数据含可打印令牌,语义未知 |
0x0330 |
0x0331 |
设备信息;响应中出现 FH8626V100 和固件能力字段 |
0x0608 |
0x0609 |
配置查询/响应,具体含义未知 |
0x0616 |
0x0617 |
配置查询/响应,具体含义未知 |
0x031A |
0x031B |
配置查询/响应,具体含义未知 |
0x0372 |
0x0373 |
配置查询/响应,具体含义未知 |
0x8164 |
0x8165 |
配置查询/响应,具体含义未知 |
0x0001 |
0x0002 |
媒体能力/流信息;响应中可识别 1920×1080 等参数 |
服务器在问候完成后发送一个 540 字节、包含 16 条记录的配置包。当前本地服务器按抓包原样发送该包,尚未证明其中哪些记录是启动媒体上传的最小必需项。
5. 已验证的设备命令
| 功能 | 请求命令 | 请求数据 | 响应命令 | 可靠层 |
|---|---|---|---|---|
| 云台移动/停止 | 0x1001 |
8 字节方向数据 | 无控制响应 | 摄像头 ACK |
| 初始化对讲 | 0x0006 |
16 字节音频参数 | 0x0006 |
双方 ACK |
| 夜视开关 | 0x8166 |
8 字节模式数据 | 0x8167 |
双方 ACK |
| 重启 | 0x8114 |
4 字节全零 | 0x8115 |
双方 ACK |
| 移动跟踪 | 0x817C |
16 字节开关数据 | 0x817D |
双方 ACK |
请求收到可靠层 ACK,说明摄像头已接收该请求;对应控制响应可用于进一步确认设备处理流程。本地页面目前以请求 ACK 作为即时操作结果。
5.1 云台 0x1001
云台数据固定为 8 字节:
1 | DD 08 00 00 00 00 03 00 |
方向映射:
DD |
动作 |
|---|---|
00 |
停止 |
01 |
上 |
02 |
下 |
03 |
左 |
06 |
右 |
方向后的 7 字节在当前所有样本中保持不变。虽然第二字节为 08,但证据不足以将其正式命名为速度。
完整 40 字节模板:
1 | F1 D0 00 24 D1 00 SS SS |
SS SS 是 D1 00 的大端序号。按下方向时发送移动帧,松开时以新序号发送DD=00。若未收到 ACK,可以重发同一序号。
5.2 语音对讲 0x0006 与 D1 01
开始对讲前,服务器通过 D1 00 发送 0x0006:
1 | 00 00 00 00 52 00 00 00 40 01 00 00 00 00 00 00 |
0x52:当前抓包使用的音频格式标识;0x140:每帧 320 字节;- 摄像头以
0x0006和 4 字节全零数据响应; D1 01使用独立可靠序号,从 0 开始。
单个语音 UDP 负载通常为 344 字节:
1 | F1 D0 | 01 54 | D1 01 | seq_be16 |
音频为 8kHz、单声道、G.711 A-law,320 字节对应 40ms。抓包中静音码主要为0xD5。timestamp 等于开始对讲时摄像头 D1 02 媒体时钟加 1,并在本次对讲期间保持不变;该字段的真实语义仍待验证。
摄像头通过 F1 D1 / D1 01 确认语音序号。停止对讲时没有观察到独立停止命令,服务器停止发送 D1 01 即可。
5.3 夜视 0x8166
请求数据固定为 8 字节:
1 | 关闭:05 00 00 00 00 00 00 00 |
摄像头响应 0x8167,数据为 8 字节全零。
5.4 重启 0x8114
1 | 请求:0x8114,数据 00 00 00 00 |
收到请求 ACK 后,服务端应把当前会话标为失效,清除旧对端、媒体时钟和握手去重状态。摄像头重启上线后会使用新的动态端口重新会合。
5.5 移动跟踪 0x817C
请求数据固定为 16 字节,仅首字节变化:
1 | 开启:01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
摄像头响应 0x817D,数据为 4 字节全零。该功能是摄像头自身的自动云台跟踪,不要与本地录像程序基于帧差实现的“移动侦测”混淆。
6. 视频通道
D1 02和D1 03的首批数据都能找到 Annex-B 起始码与 H.264 SPS(NAL type 7),因此两者都是视频/媒体通道,不是语音。- 常见 UDP 负载总长为 1032 字节,即 8 字节可靠层头加 1024 字节媒体片段;访问单元末片长度可变。
- 两个通道的媒体前导长度不同,包含时间戳、边界或流标识,但目前尚未完整定义。
- 现有证据不足以把
D1 02、D1 03严格命名为主码流和副码流。 - 只做设备控制时可以丢弃媒体负载,但仍必须 ACK;要直接从云协议录像,则需要继续完成乱序重组、媒体前导和 H.264 访问单元边界分析。
另外该摄像头已开放的 RTSP协议rtsp://admin:admin123456@<camera-ip>:8554/profile0,可以不依赖云协议视频重组。
7. 本地模拟服务器状态机
最小可行实现:
- 在摄像头网关接管 DNS 和发往公网 UDP
32100–32102的引导请求。 - 监听 UDP
32100、32101、32102:收到F1 00返回F1 01;收到F1 12返回F1 13,随后用F1 82指向本机会话端口。 - 会话端口收到
F1 83后,保存摄像头实际 IP、端口、token 和 device ID。 - 按顺序返回
F1 03、F1 84、反向F1 83(flag=0)。 - 发送服务器问候;收到摄像头
0x0331后发送抓包中的 540 字节配置包。 - 按逻辑通道和序号去重所有
F1 D0,及时返回F1 D1。 - 配置请求收到 ACK 后将会话标为可控制,并使用动态分配的下一
D1 00序号发送设备命令。 - 会话超时、摄像头重启或出现新
F1 83时,清除旧状态并重新握手。
实现注意事项:
- 不要写死摄像头 DHCP 地址、本地 UDP 源端口、云端节点或会话端口。
- 控制序号和对讲序号分别维护。
- ACK 等待应按“通道 + 序号”匹配。
- 同一可靠包的重传只能执行一次副作用。
- Linux 网关上若同时通过原始链路抓包和 UDP socket 收包,可能看到同一数据报两次;只能抑制极短时间内的本机重复投递,不能误删正常协议重传。
8. 尚未确认的部分
F1 12中变化字段的算法,以及服务端是否应校验设备签名或密钥。F1 13、F1 40、F1 41中所有字段的完整语义。0x0010会话问候中令牌的生成方法、有效期和跨重启稳定性。- 540 字节配置包中每条记录的准确含义及真正的最小初始化集合。
D1 02、D1 03的完整媒体前导、分帧、乱序重组和双通道关系。- 对讲帧
timestamp为什么取视频媒体时钟加 1,以及长时间会话是否需要更新。 - 夜视模式值、移动跟踪和其他
0x81xx命令在不同固件上的兼容性。 - 摄像头控制响应只代表接受、执行完成,还是最终硬件状态;目前页面主要依赖可靠
层 ACK,并未实现独立状态回读。
上述命令只在固件 V30023.1.145.20240716、平台 FH8626V100 的这台设备上由抓包验证。换型号或升级固件后,应重新抓包逐字节核对再发送。