- SOME/IP header
出于互操作性的原因,所有SOME/IP的实现都应具有相同的标头布局如图1中显示。字段按传输顺序呈现,即左上方的字段首先进行传输。在接下来的章节中,将描述不同的标头字段及其用途。
1.1. IP地址/端口号
图1中的布局显示了在IP和所使用的传输协议上的基本头部布局。这种格式也可以很容易地在AUTOSAR中实现。有关套接字处理的详细信息,请参阅AUTOSAR Socket Adaptor SWS。
1.1.1. IP地址和端口的映射
对于响应和错误消息,传输协议的IP地址和端口号应与请求消息相匹配。这意味着:
-
响应的源IP地址 = 请求的目标IP地址。
-
响应的目标IP地址 = 请求的源IP地址。
-
响应的源端口 = 请求的目标端口。
-
响应的目标端口 = 请求的源端口。
-
传输协议(TCP或UDP)保持不变。
1.1.2. 消息ID [32位]
消息ID是一个32位标识符,用于将RPC调用分派给应用程序的方法并标识通知。消息ID必须能够唯一标识一个方法。
消息ID的分配由用户自行决定;然而,消息ID必须在整个系统(即车辆)中是唯一的。消息ID可以最好地与CAN ID进行比较,并应使用类似的处理过程进行处理。下一节将描述如何构造消息ID的结构,以便简化消息ID的组织。
1.1.2.1. 消息ID的结构
为了对不同的方法和事件进行结构化,它们被分组成服务。服务包括一组方法和事件,以及一个仅用于该服务的服务ID。事件还可以被分组成事件组,以简化事件的注册过程。
对于RPC调用,我们将ID结构化为2^16个服务,每个服务有2^15个方法:
|-----------------------|-------------|---------------------------|
| Service ID [16 Bit] | 0 [1 Bit] | Method ID [last 15 Bit] |
使用16位的服务ID和以0位开始的16位的方法ID,这样可以支持最多65536个服务,每个服务最多有32768个方法。
由于事件(参见通知或发布/订阅)使用RPC进行传输,因此事件的ID空间进一步进行了结构化:
|-----------------------|-------------|--------------------------|
| Service ID [16 Bit] | 0 [1 Bit] | Event ID [last 15 Bit] |
1.2. 长度 [32 位]
Length是一个32位字段,包含以请求ID/客户端ID开头的有效载荷的字节长度。长度不包括包含消息ID和长度字段的头部部分,因为它基于AUTOSAR Socket Adaptor的功能。
1.3. 请求ID [32位]
请求ID允许客户端区分对同一方法的多个调用。因此,请求ID必须在单个客户端和服务器组合中是唯一的。在生成响应消息时,服务器必须将请求ID从请求复制到响应消息中。这使得客户端可以将响应映射到已发出的请求,即使存在多个未完成的请求。
请求ID可能在响应到达或不再预期到达(超时)后被重新使用。在大多数汽车应用场景中,预计只会有很少数量的未完成请求。对于没有并行请求可能性的小型系统,请求ID可能始终设置为相同的值。
对于AUTOSAR系统,请求ID需要按照下一节所示的结构进行组织。即使对于非AUTOSAR系统,建议按照下一节所示的方式对调用者的客户端ID进行编码。
1.3.1. 请求ID的结构
在AUTOSAR中,请求ID由客户端ID和会话ID构成:
|-----------------------|------------------------|
| Client ID [16 Bits] | Session ID [16 Bits] |
客户端ID是ECU内部调用客户端的唯一标识符。会话ID是由客户端为每个调用选择的唯一标识符。如果不使用会话处理,会话ID应设置为0x0000。
1.4. 协议版本号 [8位]
协议版本是一个8位字段,包含当前的SOME/IP协议版本,应设置为0x01。
1.5. 接口主版本号 [8位]
接口主版本号是一个8位字段,包含服务接口的主版本号。
原因:这是为了捕获服务定义中的不匹配,并且如果使用版本号,它允许调试工具识别使用的服务接口。
1.6. 消息类型 [8位]
消息类型字段用于区分不同类型的消息,可以包含以下值:
|--------|-----------------------|----------------------------------|
| Number | Value | Description |
| 0x00 | REQUEST | 请求 - 期望获得响应(即使是void) |
| 0x01 | REQUEST_NO_RETURN | 请求无返回 - 一次性请求 |
| 0x02 | NOTIFICATION | 通知 - 请求通知/事件回调,不期望有响应 |
| 0x40 | REQUEST ACK | 请求确认 - REQUEST(可选) |
| 0x41 | REQUEST_NO_RETURN ACK | 请求无返回确认 - REQUEST_NO_RETURN(信息性) |
| 0x42 | NOTIFICATION ACK | 通知确认 - NOTIFICATION(信息性) |
| 0x80 | RESPONSE | 响应 - 响应消息 |
| 0x81 | ERROR | 错误 - 响应包含错误信息 |
| 0xC0 | RESPONSE ACK | 响应确认 - RESPONSE(信息性) |
| 0xC1 | ERROR ACK | 错误确认 - ERROR(信息性) |
常规请求REQUEST(消息类型0x00)在没有错误发生时将由响应消息RESPONSE(消息类型0x80)进行回答。如果发生错误,将发送错误消息ERROR(消息类型0x81)。还可以发送没有响应消息的请求REQUEST_NO_RETURN(消息类型0x01)。对于通过通知NOTIFICATION进行值更新,存在一个回调接口(消息类型0x02)。
对于所有的消息,都存在可选的确认(ACK)。这些可以在传输协议(例如UDP)不确认接收到的消息的情况下使用。只有当接口规范要求时,才会传输ACK。目前,本文档仅指定了使用REQUEST_ACK。所有其他ACK目前仅作为信息提供,无需实现。
1.7. 返回码 [8位]
返回码用于指示请求是否成功处理。为了简化头部布局,每个消息都传输返回码字段。
类型为REQUEST、REQUEST_NO_RETURN和Notification的消息必须将返回码设置为0x00(E_OK)。特定消息类型的允许返回码如下:
|-------------------|--------------------------------|
| Message Type | Allowed Return Codes |
| REQUEST | N/A (无需设置)设置为0x00 (E_OK) |
| REQUEST_NO_RETURN | N/A (无需设置)设置为0x00 (E_OK) |
| NOTIFICATION | N/A (无需设置)设置为0x00 (E_OK) |
| RESPONSE | 详细的描述将在后面的博客中介绍 |
| ERROR | 详细的描述将在后面的博客中介绍,不得为0x00 (E_OK) |
确认消息类型应从待确认的消息中复制返回码。
1.8. 负载 [可变大小]
参数被携带在负载字段中。参数的序列化将在下一部分中进行规定。
负载字段的大小取决于所使用的传输协议。在UDP中,负载大小可以在0到1400字节之间。将负载限制为1400字节是为了允许将来对协议栈进行更改(例如切换到IPv6或添加安全手段)。由于TCP支持负载的分段,因此自动支持更大的大小。