4. DoIP车辆发现与路由激活:车辆声明报文(VAM)、路由激活请求/响应、激活失败常见原因

好,我们进入DoIP诊断的实战核心环节。这一章要聊的,是你在诊断仪和ECU之间建立通信通道时,必须跨过的两道坎:车辆发现路由激活

说白了,你拿着诊断仪连上车载以太网,第一步不是直接发诊断请求,而是先要“找到”车,再“告诉”车你想跟它说话。这两步走不对,后面全是白搭。

4.1 车辆声明报文(VAM)——车在喊“我在这儿”

车辆声明报文,英文叫Vehicle Announcement Message,简称VAM。它的作用很简单:车辆主动告诉网络上的所有设备,我上线了

你想想看,诊断仪刚接入车载网络,它怎么知道有哪些ECU在线?总不能一个个去猜吧。DoIP的设计思路是:车辆端主动广播VAM。

这个报文是UDP广播,目标地址是255.255.255.255,端口是UDP 13400。车辆启动DoIP实体(通常是网关)后,会立即发送VAM,之后还会周期性重发(一般是每3秒一次,连续发3次)。

我个人习惯,在抓取DoIP通信日志时,第一件事就是过滤UDP 13400端口。如果看不到VAM,那说明车辆端的DoIP栈根本没跑起来,或者网络配置有问题。

VAM报文结构(关键字段)

  • 协议版本:当前主流是0x02(ISO 13400-2:2012)
  • 报文类型:0x0004(车辆声明)
  • VIN:17字节车辆识别码,唯一标识一辆车
  • 逻辑地址:DoIP实体的逻辑地址,通常是网关的地址
  • EID:实体ID,基于MAC地址生成,用于区分不同DoIP实体
  • GID:组ID,用于分组管理,一般填0
  • 进一步动作标志:指示车辆是否支持路由激活、诊断等

这里有个坑,我踩过。有一次在测试中,诊断仪始终收不到VAM。查了半天,发现是车辆端的防火墙把UDP广播给拦了。嗯,车载以太网虽然叫以太网,但安全策略跟IT网络一样严格。你想想看,广播报文在某些OEM的网络安全策略里是被限制的。

实战小技巧:如果你在开发诊断仪,建议同时监听UDP广播和单播。有些车辆实现中,VAM可能只发往特定的组播地址,而不是全网广播。我建议你参考ISO 13400-2的附录,那里有详细的地址分配说明。

4.2 路由激活请求/响应——建立通信通道

收到VAM之后,诊断仪知道了车辆的存在。但接下来,你需要发起路由激活。这一步的目的是:让车辆端的DoIP实体(网关)为你分配一个专用的TCP连接通道。

为什么需要这一步?因为DoIP的物理层虽然是以太网,但诊断通信走的是TCP连接。路由激活的本质,就是在诊断仪和车辆网关之间建立一条逻辑上的诊断通道

流程是这样的:

  1. 诊断仪向车辆网关的TCP 13400端口发起连接
  2. 连接建立后,诊断仪发送路由激活请求报文
  3. 车辆网关验证请求,返回路由激活响应
  4. 如果成功,后续的诊断报文(如UDS请求)就可以通过这个TCP连接发送了

路由激活请求报文

请求报文的结构如下:

协议版本: 0x02
反向协议版本: 0xFD (固定值)
报文类型: 0x0005 (路由激活请求)
源地址: 诊断仪的逻辑地址 (例如 0x0E80)
目标地址: 车辆DoIP实体的逻辑地址 (从VAM中获取)
激活类型: 0x0000 (默认,表示标准诊断)
保留位: 全0
OEM特定数据: 可选,长度可变

这里有个关键点:源地址。诊断仪的逻辑地址不是随便填的。ISO 13400-2规定了诊断仪的逻辑地址范围是0x0E00到0x0EFF。我见过有人填了0x0001,结果网关直接拒绝激活。为什么?因为0x0001是ECU的地址范围,诊断仪不能占用。

路由激活响应报文

车辆网关收到请求后,会返回响应:

协议版本: 0x02
反向协议版本: 0xFD
报文类型: 0x0006 (路由激活响应)
源地址: 车辆DoIP实体的逻辑地址
目标地址: 诊断仪的逻辑地址
响应码: 0x00 (成功) 或 其他错误码
保留位: 全0
OEM特定数据: 可选

响应码是关键。0x00表示成功,其他值表示失败。常见的失败码我们下面细说。

路由激活成功后的状态

一旦路由激活成功,诊断仪和车辆网关之间的TCP连接就变成了“诊断模式”。此时,你可以通过这个连接发送UDS诊断请求(如读取故障码、清除故障码等)。

注意:一个TCP连接只能对应一个诊断仪。如果另一个诊断仪也想激活路由,车辆网关会拒绝,除非第一个诊断仪先断开连接。

4.3 激活失败常见原因——我踩过的坑

路由激活失败,是DoIP诊断中最常见的问题之一。我总结了几种典型情况,你遇到了可以直接对照排查。

响应码 含义 常见原因
0x00 成功 一切正常
0x01 拒绝:源地址无效 诊断仪的逻辑地址不在合法范围内(0x0E00-0x0EFF)
0x02 拒绝:目标地址无效 请求中的目标地址与车辆DoIP实体的地址不匹配
0x03 拒绝:激活类型不支持 激活类型字段填了非0值,但车辆不支持
0x04 拒绝:已经激活 该TCP连接已经处于激活状态,不能重复激活
0x05 拒绝:资源不足 车辆网关的激活槽位已满(最多支持几个诊断仪同时连接)
0x06 拒绝:安全策略 车辆的安全模块拒绝了激活请求(例如需要身份认证)

我曾经遇到过一个特别隐蔽的问题。某次测试中,路由激活总是返回0x06(安全策略拒绝)。我检查了所有字段,逻辑地址、协议版本都没问题。后来发现,是车辆端的安全策略要求诊断仪必须先通过TLS握手,才能进行路由激活。嗯,DoIP也支持加密通信,但很多初学者不知道这一点。

注意:响应码0x06(安全策略拒绝)在ISO 13400-2中定义为“OEM特定”。也就是说,不同车企对这个错误码的解释可能不一样。有的车企用它表示“需要TLS”,有的表示“需要身份令牌”。遇到这个错误,建议你查阅对应OEM的DoIP实现规范。

另一个常见问题是超时。诊断仪发送路由激活请求后,车辆网关必须在规定时间内响应。ISO 13400-2规定超时时间是2秒。如果超过2秒没收到响应,诊断仪应该重试。我建议你重试3次,如果还是失败,就断开TCP连接重新建立。

还有一点,我记得有一次在实车测试中,路由激活总是失败,但用同一个诊断仪在台架上就正常。后来发现,是实车的网关固件版本太旧,不支持某些协议版本。你想想看,车辆出厂后,网关的固件可能几年都没更新过,而你的诊断仪用的是最新的协议栈,两者不兼容。

我的排查流程

  1. 抓包确认VAM是否正常发出
  2. 检查TCP连接是否建立(三次握手成功)
  3. 检查路由激活请求的源地址和目标地址
  4. 检查响应码,对照上表定位问题
  5. 如果响应码是0x06,联系OEM获取安全策略细节
  6. 如果超时,检查网络延迟和防火墙设置

最后说一句,路由激活是DoIP诊断的“敲门砖”。这块搞不定,后面的故障码读取、清除、刷写都无从谈起。我建议你在开发阶段,先把VAM和路由激活的流程跑通,用Wireshark抓包确认每一步的报文交互。等这一步稳了,再往下走。

下一章,我们会聊如何通过DoIP发送UDS诊断请求,真正开始读取故障码。到时候你会看到,路由激活成功后,诊断通信其实跟传统的CAN诊断很像,只是底层传输方式变了。