目录
1. Generic DoIP header negative acknowledge
2. Vehicle identification request/response message, Vehicle announcement message
1. 边缘节点(DoIP edge node gateway)
DoIP协议
在汽车网络通信中,诊断扮演了非常重要的角色,无论是故障筛查、整车下线配置,还是ECU的软件更新、远程OTA等,都离不开诊断技术。
传统基于CAN的诊断相信大家都不陌生,那么如果应用了车载以太网,诊断该如何实现呢?答案是DoIP。
利用DoIP协议,就可以实现基于车载以太网的诊断服务,从而借助更高速率的数据传输进行车辆诊断的相关工作。今天我们就来简单介绍一下DoIP协议。
DoIP (Diagnostic communication over Internet Protocol), 是基于以太网的通讯协议对UDS协议的数据进行传输,参考标准ISO13400。
汽车诊断使用的是UDS(ISO 14229统一诊断服务),那么使用了DoIP,是不是就不需要UDS了?这里需要注意一点,DoIP只是一个传输协议,用于传输诊断服务,在车载以太网中,UDS和在其他汽车总线技术中使用的是一致的,不同的是传输是通过DoIP实现的。
DoIP报头格式
在以太网帧中,DoIP报文是位于TCP/UDP报头后面的有效负载,如上图。DoIP报头共有四个字段:
Protocol version(协议版本):表示所使用的DoIP协议版本,长度为1字节。常见值为0x02,表示ISO 13400-2:2012(虽然现在已经更新了2019版本,但当前大多数主机厂还是遵循2012版本来使用DoIP的);
Inverse protocol version(协议版本取反):用于对协议版本进行验证,确保DoIP报文格式的正确性,长度为1字节。如协议版本为0x02,取反值应为0xFD;
Payload type(有效负载类型):表示DoIP报文所携带的有效负载类型,长度为2个字节。大致可分为三类:0x0XXX管理类、0x4XXX车辆信息类、0x8XXX诊断类,其他字段暂时被ISO 13400预留或供OEM自定义使用。
Payload length(有效负载长度):表示DoIP有效负载的数据长度。
Payload type specific message content(DoIP报文内容,也就是DoIP的有效负载),不同类型DoIP有效负载的格式和长度都不尽相同。
DoIP有效负载类型
上文我们提到了DoIP报文的有效负载有多种类型,下表类型为负载字段的不同值所对应的报文内容:
1. Generic DoIP header negative acknowledge
DoIP报头否定响应报文 (0x0000),当DoIP实体接收到DoIP报头中某些字段有误的报文时,需回复Generic DoIP header NACK报文,并携带标识错误信息的NACK code。如:接收到Payload type字段未知的DoIP报文、Payload length字段与实际报文长度不一致的DoIP报文等情况,均需回复DoIP header NACK报文,其报文格式如下:
此类型报文在报头后面只会携带一个字节的DoIP header NACK code字段,其不同值的含义如下:
2. Vehicle identification request/response message, Vehicle announcement message
车辆识别和车辆声明报文 (0x0001, 0x0002, 0x0003, 0x0004),此类报文用于识别和确认网络上的被诊断车辆。诊断仪可通过其获取车辆的VIN(Vehicle Identification number)、GID(Group identification)和DoIP实体的逻辑地址等信息。
ISO 13400中规定,当DoIP实体获取了有效的IP地址后,应在500 ms内发送3条Vehicle announcement message,用于声明自己的车辆信息,具体实现的时候,发送时间和条数可以根据主机厂的需求进行调整。因为是以UDP的方式进行发送,为了尽可能保证报文可被正确接收,所以要发送多次,同时报文的目的IP地址设置为本地限制广播地址(255.255.255.255)。其报文格式如下:
VIN:车辆识别码;
Logical Address:DoIP实体的逻辑地址,用于直接将诊断请求指向某个DoIP实体,此字段在诊断报文中还会出现;
EID:DoIP实体的唯一识别ID,建议设置为DoIP实体节点的MAC地址,在车辆还未配置VIN时,可以用EID来标识DoIP实体,通常应用于车辆装配阶段;
GID:同一辆车上多个DoIP实体组的标识。
当传输这条报文时,如果这几个字段还未被设置,应设置为全0或全1的无效值。
最后两个字段分别为1字节的Further action required和VIN/GIN sync. Status。
DoIP汽车网络传输架构
图中分为车内网(Vehicle network)和车外网(External network),车内网和车外网之间,有两组重要的线束,其中
1. 一组是用于数据传输的以太网线:就是我们常见的四线制TX标准网线
2. 一组是用于诊断功能激活的激活线:是用于车内诊断功能的激活。出于能耗和电磁干扰的考虑,要求非诊断通信期间,与诊断相关的功能处于关闭状态,这样一方面可以降低能耗,另一方面减少对网络带宽的消耗,从而降低电磁干扰。
车内网(Vehicle network)
1. 边缘节点(DoIP edge node gateway)
直接与外部诊断仪进行物理连接的节点,叫做边缘节点(DoIP edge node)。
1. 边缘节点可作为一个网络交换机,将车内网与车外网组成同一子网;
2. 也可以作为一个网关,将车内网与车外网进行安全隔离,屏蔽非法的网络访问和网络攻击。
2. DoIP网关节点(DoIP gateway)
除了边缘节点之外,还有另一类网关,即车内的DoIP网关节点。
车内DoIP网关节点的作用,是实现以太网到其他网络总线(如CAN、LIN)的报文路由,这样便实现了DoIP诊断与传统网络总线的兼容。
多种网络总线汇聚到DoIP网关,这大大的降低了布线的复杂性,并且提高了各总线网络中ECU的诊断效率。
3. DoIP节点
车内网络中,还存在一般的DoIP节点,这些节点只支持对自身的诊断,而不具备路由功能。
4. 网络节点(Network node)
最后,还有一类网络节点(Network node),不具备DoIP诊断功能,与DoIP节点共享网络资源。
对于边缘节点,人们经常通常有以上的疑问,其实透传和非透传这两种方案,没有好坏之分,都有各自适合的应用场景。
例如,连接的外接诊断仪,主要用于多车故障诊断和ECU刷写,为了实现快速的ECU访问和在线监测,要求车内各ECU享有唯一的IP地址,适合使用透传方案。
若连接的是TBOX之类具有联网功能控制单元,为了避免车内网受到外部网络攻击,因此适合使用非透传方案。
DoIP协议的主要功能
DoIP协议栈作为以太网诊断软件架构的中间件,主要具备如下五大功能,这五大功能体现了DoIP诊断的特殊性,是区别于传统CAN诊断的重要特征。
接下来我们按照DoIP诊断从连接建立到诊断通信实施的流程,对各个功能模块进行简要讲解。
车辆发现
顾名思义,就是用来检测车辆是否在线,具体来说就是诊断仪首先发送一个广播的车辆发现报文,网络中所有接收到这条报文的ECU都将发送自己的身份信息。通过各个ECU发回的身份信息,诊断仪便可以准确得获知有哪些ECU在线,并且可以根据这些信息对这些ECU进行归类,比如各自属于那一台汽车。
路由激活
与传统意义上网关的“路由”不同,DoIP协议中的“路由”指的是诊断仪与被诊断节点之间的报文传输。外部测试仪与DoIP节点之间的通信连接建立之后,应发送路由激活请求,路由激活请求被DoIP节点验证合法之后,诊断仪才能对ECU进行诊断。路由激活包含了DoIP节点对外部诊断仪的安全认证过程,ECU开发人员可以自定义安全认证的算法,用于屏蔽非法诊断仪对ECU进行的诊断。
诊断仪在线监测
与传统CAN总线不同,DoIP诊断需要预先与ECU建立通信连接,也就是TCP socket。由于socket的建立会消耗内存资源,因此不能无限制创建连接。ECU在设计阶段,会定义最多能支持并行连接的诊断仪数量,并行连接的诊断仪数量达到上限之后,将无法建立新的诊断通信连接。因此这些诊断连接通道属于稀缺的资源,为了避免通道被无效占用,因此设计了诊断仪在线监测机制。DoIP节点会向现在有的诊断连接通道上,发送诊断仪在线监测请求,若有的连接上无法收到诊断仪回复的响应报文,则会将此连接复位,以待新的诊断仪接入。
节点信息
节点信息包含了节点的属性,例如如最大支持的并行诊断仪连接数量,最大可接受的诊断报文长度,以及当前节点的电源状态,即是否所有部件都完成上电。节点信息作为诊断通信前的诊断条件检查,以确保后续诊断通信不受外部因素干扰。
诊断通信
作为DoIP协议的核心功能,此功能负责诊断报文的传输。诊断报文中包含三个信息,即诊断报文发送方的逻辑地址(以下简称SA),诊断报文接收方的逻辑地址(以下简称DA),以及诊断数据。在CAN总线网络中,通过CANID来寻址要诊断的ECU,而在DoIP网络中,DA的作用相当于CANID,用于寻址要诊断的目的ECU。下图通过一个以太网转CAN的诊断示例,展示SA和DA在诊断通信中的作用。
DoIP会话
下面我们结合一个完整的DoIP会话,来帮大家梳理下上文介绍到的这些报文类型是如何应用的
1 诊断仪连接车辆,物理连接建立;
2 配置IP地址,配置的方法有两种,DHCP和Auto-configuration,当DHCP配置不成功时,才会启动Auto-configuration。在DHCP流程中,通常由外部诊断仪来扮演DHCP Server;
3 DoIP实体主动发送3次Vehicle announcement message;
4 当未收到DoIP实体发送的Vehicle announcement message时,诊断仪应主动发送Vehicle identification request,DoIP实体接收并响应Vehicle identification response。如收到Vehicle announcement message,此步骤可跳过;
5 当车辆识别后,诊断仪应发起TCP同步,和DoIP实体建立TCP连接;
6 TCP连接建立后,诊断仪应发送Routing activation request,DoIP实体接收并响应Routing activation response,DoIP逻辑连接建立;
7 接下来就可以进行诊断服务的传输了,诊断仪发送Diagnostic message request,DoIP实体接收并响应Diagnostic message response。这里图中的DoIP message ACK是DoIP层级的确认报文(0x8002,0x8003)。
图中出现了四个端口号,UDP_DISCOVERY,UDP_TEST_EQUPMENT,TCP_DATA和动态分配。车辆发现的过程是通过UDP进行数据传输的,在ISO 13400中规定,UDP_DISCOVERY为13400端口,UDP_TEST_EQUPMENT和动态分配的端口号可以在私有端口号中动态选择(49152 – 65535)。诊断会话是通过TCP进行数据传输的,在ISO 13400中规定,TCP_DATA为13400端口,在DoIP工作期间,DoIP实体应持续监听13400端口。以上就是一个完整的DoIP诊断会话。
DoIP逻辑地址
在车载以太网通信中,因为数据是逐层进行封装和处理的,所以在OSI网络模型中,从数据链路层开始,每一层都会有用于标识发送端或接收端的特定地址,如数据链路层的MAC地址、VLAN ID,网络层的IP地址和传输层的端口号。在DoIP层级中,用来标识DoIP实体的地址为DoIP逻辑地址(Logical address):
ISO 13400中将逻辑地址分为物理逻辑地址(Physical logical address)和功能逻辑地址(Functional logical address),类似CAN中的物理寻址和功能寻址。
在车辆发现的过程中,收发两端会将对方的逻辑地址与IP地址进行映射,保证之后可正确进行诊断会话。
逻辑地址长度为2个字节,在车辆声明报文、路由激活报文和诊断报文中都会携带,其定义规则如下表:
表中我们最常见的逻辑地址范围为ECU的逻辑地址(0x0001 — 0x0DFF & 0x1000 — 0x7FFF)和诊断仪的逻辑地址(0x0E00 — 0x0FFF)。
此外,有四个需要注意的地方:
a & b : 此逻辑地址块供合法的诊断检测设备或售后诊断设备使用,当出现此类逻辑地址时,其他诊断通信应停止,同时也会减少其他正常功能的通信行为。
c : 此逻辑地址块仅供OEM的内部数据收集或OBD诊断设备使用,不能被外部测试设备使用;
d : 此逻辑地址块供安装在车辆上的长期数据采集设备使用,当接收到此类地址的路由激活请求时,DoIP实体会选择拒绝或延时处理,以防止其影响车内正常的数据交互。
DoIP逻辑连接
DoIP的诊断会话过程是基于TCP实现的,我们知道TCP是面向连接的传输协议,那DoIP是否可以完全依赖于TCP本身的连接来进行数据的交互呢?不完全是,DoIP也有一套自己的连接方式,称之为逻辑链接,其在TCP连接的基础上增加了逻辑地址的概念。DoIP实体通过TCP的五元组(源IP地址、目的IP地址、源端口号、目的端口号、协议类型)加逻辑地址来识别唯一的DoIP连接。下图为DoIP逻辑连接的状态机:
1. 逻辑连接的初始状态为Listen;
2. 当TCP连接建立并进入ESTABLISHED状态后,逻辑连接跳转至Initialized状态并启动Initial inactivity timer;
注:Initial inactivity timer,当DoIP逻辑连接处于Initialized状态时,如未收到有效的路由激活报文,当Initial inactivity timer超时后,DoIP实体会主动关闭此类无效的初始连接。ISO 13400中建议其初始值为2秒。
3. 当接收到诊断仪发送的正确的路由激活报文后,跳转至Registered [pending for authentication] 状态,停止Initial inactivity timer并开启General inactivity timer;
注:General inactivity timer,当DoIP逻辑连接处于Registered状态时,如一段时间之内没有数据的收发行为发生,当General inactivity timer超时后,DoIP实体会主动关闭此类不活跃连接。ISO 13400中建议其初始值为5 分钟,计时器在每一次数据收发时均会被重置为初始值。
4. Registered [pending for authentication] 状态下,如认证完成或无需认证,跳转至Registered [pending for confirmation];如果认证失败、General inactivity timer超时或Alive check报文无响应,会跳转至Finalize状态;
5. Registered [pending for confirmation] 状态下,如确认完成或无需确认,跳转至 Registered [routing active],到此状态,DoIP逻辑连接激活完成,可以开始进行诊断会话。如果确认失败、General inactivity timer超时或Alive check报文无响应,会跳转至Finalize状态。
状态机中认证(Authentication)和确认(Confirmation)的方法在ISO 13400中并无定义,如果有需求,可使用路由激活报文中的Activation type和Reserved for OEM-specific use字段来实现。
DoIP参数设置
在车辆发现和诊断会话的过程中,ISO 13400定义了若干个时间参数和计时器,用于保证DoIP通信的正常工作,比如上文中的Initial inactivity timer和General inactivity timer,详情见下表:
其中有些参数看起来比较抽象,下面我们通过图示来介绍下他们是如何工作的:
DoIP真实交互数据
下面我们来看几组真实的DoIP报文交互,Wireshark和CANoe为目前常用的两款可以分析车载以太网数据的软件,Wireshark(今天发现wiki上把Wireshark翻译成“导线鲨鱼”,有点意思)在互联网领域应用广泛,开源、功能强大同时免费,并且新版的Wireshark已经可以解析车载网络中的SOME/IP、DoIP和UDS等协议,方便易用。
下图是使用Wireshark抓取了几条DoIP报文,包括两条路由激活报文和三条诊断报文(已隐去部分IP地址和逻辑地址):
有的同学在抓包的时候有可能会出现下图的情况,这是因为DoIP诊断会话是通过TCP传输的,所以每次接收端都会响应ACK报文,为了防止这些ACK影响数据分析,我们可以在Wireshark的Filter里输入“doip”,将这些TCP的功能报文过滤掉。
下面我们来具体看一下这些报文的数据内容:
Frame No. 12,Routing activation request:
Payload type字段为0x0005,为诊断仪发送的路由激活请求报文,携带了诊断仪的逻辑地址0x0eXX,激活类型为Default 0x00
Frame No. 14,Routing activation response:
Payload type字段为0x0006,为DoIP实体回复的路由激活响应报文,携带了诊断仪和DoIP实体本身的逻辑地址0x0eXX和0x04XX,路由激活响应码为0x10,表示路由激活请求成功,之后就可以进行诊断报文的交互了。
Frame No. 20,Diagnostic message(Request):
Payload type字段为0x8001,为诊断报文,由诊断仪发给被诊断节点,携带了两端的逻辑地址,Payload部分为UDS 10服务,子功能03,表示进入扩展会话模式。
Frame No. 21,Diagnostic message ACK:
Payload type字段为0x8002,为诊断包报文的ACK,当上一条诊断报文没有错误并可以正确处理时,会回复此报文,仅表示DoIP层面正确,报文已被接收,不会携带UDS服务。
Frame No. 23,Diagnostic message(Response):
Payload type字段为8001,为诊断报文,携带UDS服务,对Frame No.20中的请求做出了肯定响应,进入扩展会话模式。在Wireshark中,UDS服务的Reply Flag会被单独解析,所以UDS的SID还是10,如果一起解析就变成了肯定响应SID:50。