SOME/IP-SD 是"Scalable service-Oriented MiddlewarE over IP - Service Discovery"的缩写,是SOME/IP的一种特殊报文,可以让Client知道Server可以提供哪些服务,SOME/IP有两种动态发现服务的机制:一种是Offer Service,由Server向网络上的小伙伴告知它所提供的服务;另一种是Find Service,由Client向Server请求可用的服务。
1. 简介和概述
该协议规范定义了SOME/IP-SD的格式、消息序列和语义。SOME/IP-SD主要任务是车载功能实体调用服务的通信可用性以及控制事件消息的发送行为。这种机制只允许事件消息发送给需要它们的接收者(Publish/Subscribe)。
1.1 协议的目的
SOME/IP-SD 主要用于
- 定位服务实例
- 检测服务实例是否还在运行
- 完成发布/订阅管理
1.2 协议的应用范围
SOME/IP-SD用于车载网络的服务发现,使用该协议有以下约束:
- SOME/IP-SD仅支持IP通信
- 如果客户端订阅服务是通过多播选项声明的客户端服务多播端点,则网络通信设计必须考虑以下限值:
- 基于点对点连接的通信可能无法正常工作(例如端到端相关通信、IPsec通信)。
- 初始化事件必须谨慎使用,因为所有客户端服务都订阅了相同的组播端点到相同的服务器服务,每次新的客户端服务使用相同的组播端点订阅到相同的服务器服务时,都会接收初始化事件
1.3 依赖
1.3.1 协议层依赖
从下图可以看出SOME/IP-SD是基于SOME/IP协议,而SOME/IP协议是基于TCP或UDP协议,但是SOME/IP-SD只能基于UDP协议。
2 用例
ID | Name | Description |
---|---|---|
UC_001 | 提供服务 | 服务端向网络提供服务,而不需要在客户端静态配置服务器 |
UC_002 | 订阅服务 | 客户端在不知道发送者位置的情况下找到所需的服务并订阅它 |
UC_003 | 灵活的通信路径 | 开发人员希望在不知道谁将接收数据或谁将发送所需数据的情况下设计应用程序。服务发现允许在集成期间建立通信路径。 |
3 协议需求列表
略
4 术语和缩略语
术语/缩略语 | 描述 |
---|---|
Byte Order Mark | 字节顺序标记(byte order mark, BOM)是一个Unicode字符,U+FEFF字节顺序标记(byte order mark, BOM),它作为一个魔数出现在文本流的开头,用于表明所使用的编码 |
Method | 可被调用的方法、过程、函数或子程序 |
Parameters | 方法或事件的输入、输出或输入/输出参数 |
Remote Procedure Call (RPC) | 从一个ECU到另一个ECU的方法调用,使用消息传输 |
Request | 客户端发给服务端用来调用方法(Method)的消息 |
Response | 服务端响应客户端方法调用的消息 |
Request/Response communication | 一次请求/回复过程,也就是RPC |
Event(事件) | 单向数据传输,只在变化时调用或循环调用,从数据的生产者发送到消费者 |
Field | Field(字段)代表一种状态,因此在getter、setter和notifier操作的任何时候都有一个有效值 |
Notification Event | 用字段通知的事件消息 |
Getter | 允许读取字段的请求/响应调用。 |
Setter | 允许对字段进行写访问的请求/响应调用。 |
Service | 零个或多个方法、零个或多个事件、零个或多个字段的逻辑组合。 |
Eventgroup | 一个服务中事件和字段通知事件的逻辑组合,以便允许订阅 |
Service Instance | 一个服务的实现,它可以在车辆上多次存在,也可以在ECU上多次存在 |
Server | 提供服务实例的ECU在这个服务实例的上下文中应该被称为服务器。 |
Client | 在这个服务实例的上下文中,使用服务器服务实例的ECU应该被称为客户端。 |
Fire and Forget | 无回复的请求叫做 解雇并遗忘 |
User Datagram Protocol | 一种传输层协议 |
Union | 一种动态假设不同数据类型的数据结构 |
non-extensible (standard) struct | 序列化时不带标签的结构体。最多可以在结构体末尾以兼容的方式添加新成员,而不能添加可选成员。 |
extensible struct | 用标签序列化的结构体。可以在任意位置以兼容的方式添加新成员,也可以添加可选成员。 |
5 协议规范
5.1 SOME/IP-SD
5.1.1 概览
SOME/IP-SD 主要用于
- 定位服务实例
- 检测服务实例是否还在运行
- 完成发布/订阅管理
车辆内部的服务实例的位置通常是已知的;因此,服务实例的状态是主要关注的问题。服务的位置(即ip地址、传输协议和端口号)是次要的。
如果需要在多个网络接口上提供服务,则每个网络接口应提供一个单独的服务端服务实例
如果需要将服务配置为使用多个不同的网络接口访问,则每个网络接口应使用一个单独的客户端服务实例
5.1.2 SOME/IP-SD消息格式
SOME/IP-SD 消息的字段组成如下:
- Message ID(Service ID/Method ID)[32 bit]: 0xFFFF 8100
- Length [32 bit]
- Request ID (Client ID/Session ID) [32 bit]
- Protocol Version [8 bit]: 0x01
- Interface Version [8 bit]: 0x01
- Message Type [8 bit]: 0x02
- Return Code [8 bit]: 0x00
- Flags [8 bit]
- Reserved [24 bit]
- Length of Entries Array [32 bit]
- Entries Array [variable size]
- Length of Options Array [32 bit
- Options Array [variable size]
字段结构如下图所示:
- SOME/IP-SD报文的Service ID固定为0xFFFF8100
- SOME/IP-SD报文应该将Client-ID(16位)设置为0x0000,因为只存在一个SOME/IP-SD实例
- 服务发现消息应该有一个Session-ID(16位),并根据某些/IP要求处理它,每发出一个SOME/IP-SD报文,Session-ID加1,只能从1开始,不能设置为0。SOME/IP-SD会话ID处理是根据“通信关系”完成的,即组播和单播是对等的
- Protocol Version [8 bit]:固定为0x01,Interface Version [8 bit]固定为0x01,Message Type [8 bit]固定为0x02,Return Code [8 bit]固定为0x00
下图为一个完整的SOME/IP-SD PDU实例展示:
5.1.2.2 SOME/IP-SD 头部
SD头部以8位字段“flags”开始,字段的表示如下图5.3所示
- 该字段第0位表示"Reboot Flay"。SOME/IP-SD首部的重启标志应该设置为1,直到SOME/IP首部中的Session-ID绕回0(wraps around),重新从1开始。换行之后,重新启动标志设置为0。
- 对于多播和单播,重启标志和会话ID的信息应该分别保存
- 每次发送-接收都要单独保存重启标准和会话ID信息(比如源地址和目的地地址)
注意:这意味着不管是发送方还是接收方都要单独计数
-
发送方:需要为多播设置一个计数器,也需要为单播设置一个计数器
-
接收方:对于组播,每个对等体都应该有一个计数器;对于单播,每个对等体都要有一个计数器
-
检测重启的方法如下(使用来自通信伙伴的当前数据包的新值和之前接收到的最后一个值):
if old.reboot == 0 and new.reboot==1 then Reboot detected;
if old.reboot 1 and new.reboot1 and old.session_id>=new.session_id then Reboot detected -
第二个标志位叫单播标志位(Unicast Flag),所有SD消息该位都要设置成1。单播标志是从历史的SOME/IP版本遗留下来的,只是出于兼容性的原因而保留。除此之外,它的用途非常有限。
-
Flags 字段未定义的位都要设置成0
-
在Flags字段后,需要有24位作为保留字段
-
条目字段以序列化的顺序为准
-
SOME/IPSD消息的Entries数组和Options数组应该以length字段作为uint32开始,该字段统计了以下数据的字节数;即条目或选项。
5.1.2.3 条目格式(Entry format)
SD报文协议应支持一条SD报文里可以包含多个条目。这些条目用于同步服务实例的状态和发布/订阅处理。
协议中有两种条目:一种服务条目,另一种事件组条目。
服务条目有16个字节大小,包含的字段如下所示:
- 类型字段[uint8]:FindService (0x00), OfferService (0x01) and StopOfferService (0x01)
- 第一个选项运行索引[uint8]:代表选项排列中第一个选项索引位置
- 第二个选项运行索引[uint8]:代表选项排列中第二个选项索引位置
- 选项1的数量[uint4]:描述第一个选项运行使用的选项数量
- 选项2的数量[uint4]: 描述第二个选项运行使用的选项数量
- Service-ID[uint16]: 描述此条目所关注的服务或服务实例的服务ID。
- Instance ID[uint16]: 描述此条目所涉及的服务实例的服务实例ID,如果表示一个服务的所有服务实例,则设置为0xFFFF
- Major Version[uint8]: 服务(实例)的主版本
- TTL[uint24]: 描述条目的生命周期,单位为秒
- Minor Version[uint32]: 服务的次版本
服务条目的字段结果如下图所示:
事件组条目一共16个字节,它包含以下字段:
- 类型字段[uint8]:Subscribe (0x06), StopSubscribeEventgroup (0x06),
SubscribeAck (0x07) and SubscribeEventgroupNack (0x07). - 第一个选项运行索引[uint8]:代表选项排列中第一个选项索引位置,0表示第一个SOME/IP-SD报文
- 第二个选项运行索引[uint8]:代表选项排列中第二个选项索引位置,0表示第一个SOME/IP-SD报文
- 选项1的数量[uint4]:描述第一个选项运行使用的选项数量。0表示没有选项
- 选项2的数量[uint4]: 描述第二个选项运行使用的选项数量。0表示没有选项
- Service-ID[uint16]: 描述此条目所关注的服务或服务实例的服务ID。
- Instance ID[uint16]: 描述此条目所涉及的服务实例的服务实例ID,如果表示一个服务的所有服务实例,则设置为0xFFFF
- Major Version[uint8]: 编码这个eventgroup所属的服务实例的主版本。
- TTL[uint24]: 描述条目的生命周期,以秒为单位
- 保留字段[uint12]: 设置成0x000
- Counter[uint4]: 用于区分同一订阅服务器的相同订阅事件组。如果不使用,设置为0x0。
- Evntgroup ID[uint16]: 传输事件组的ID
对于经典平台上的服务发现,SdServerService主版本和SdClientService主版本分别需要与对应服务接口的接口版本匹配
5.1.2.4 选项格式(Options Format)
Options用于将附加信息传输给条目"Entries",包括例如如何访问服务实例的信息(IP地址、传输协议、端口号)
为了识别Option类型,每个Option都应以下面字段开始:
- Length字段,uint16,表示这个Option的字节数
- Type字段,uint8,表示这个Option的类型
- Discardable Flag,1个bit,表示该Option是否可丢弃
- Bit1到Bit7是保留位,设置为0
Length字段表示该Option除了Length字段和Type字段外的所有字节数, 如果接收方ECU不支持该Option,且可以丢弃它,那么Discardable Flag应该设置为1
Option的种类如下:
Configuration Option
“配置选项”用于传输任意的配置字符串,这允许对附加信息进行编码,例如服务名称或是它的配置
“配置选项”的格式如下:
- Length字段,2个byte,表示该配置选项的字节数,不包括Length字段和Type字段
- Type字段,1个byte,应设置为0x01
- Discardable Flag,1个bit,如果该配置选项可以被接收方丢弃,则应设置为1
- Bit1到Bit7是保留位,设置为0
- ConfigurationString,动态长度,该字段携带配置字符串
– 配置选项应指定一组基于DNS TXT和DNS-SD格式的"名称-值"对
– 配置字符串的格式应以单个字节长度字段开始,该字段描述该长度字段之后的字节数。在长度字段之后应遵循具有指定长度的字符序列
– 在每个字符序列之后,期望另一个长度字段和随后的字符序列,直到长度字段应设置为0x00
– 将长度字段设置为0x00后,不得跟随任何字符
– 一个字符序列应该编码一个键和一个可选的值
– 字符序列应包含一个相等的字符(“=”,0x3D)来划分键和值
– 键不应包含相等的字符,并且应至少是一个非空白字符。“Key”的字符应为可打印的US ASCII值(0x20-0x7E),不包括‘=’(0x3D)
– “=”不应是序列的第一个字符
– 对于没有“=”的字符序列,该键应被解释为存在
– 对于以“=”结尾的字符序列,该键应被解释为具有空值
– 应支持在单个配置选项中具有多个相同键的条目
配置选项的格式为:
- Length字段,2个byte
- Type字段,1个byte,0x01
- Reserved,1个byte,0x00
- 以零结尾的配置字符串,可变长度
负载平衡选项(Load Balancing Option)
负载平衡Option用于区分服务的不同实例的优先级,以便客户端根据这些设置选择服务实例。此Option附加在Offer Service Entries的后面
负载平衡选项应携带与DNS-SRV记录类似的优先级和权重,用于对不同服务实例进行负载平衡
在查找服务的所有服务实例时(服务实例设置为0xFFFF),客户端应选择具有最高优先级且也符合客户端特定标准的服务实例
当有多个具有最高优先级(Priority字段中的最低值)的服务实例时,应根据服务实例的权重随机选择服务实例。选择服务实例的概率应为服务实例的权重除以所有考虑的服务实例的权重之和
如果一个Offer Service Entry没有引用负载平衡选项并且提供了多个服务实例,则客户端应按照最低优先级处理没有负载平衡选项的服务实例
在查找某个服务的特定服务实例时(Service Instance设置为0xFFFF以外的任何值),Load Balancing Option的优先级不适用
负载平衡选项的格式如下:
- Length字段,2个byte,应设置为0x0005
- Type字段,1个byte,应设置为0x02
- Discardable Flag,1个bit,如果选项可以被接收方丢弃,则应设置为1
- Bit1到Bit7是保留位,全部为0
- Priority字段,2个byte,携带此实例的优先级。较低的值意味着较高的优先级
- Weight字段,2个byte,承载此实例的重量。值大意味着被选中的概率更高
IPv4 Endpoint Option
IPv4端口Option被SOME/IP-SD实例用于向相关端口发出信号。端口包括本地IP地址、传输层协议(例如UDP或TCP)以及发送方的端口号。这些端口也用于事件和通知事件
IPv4端口Option的格式如下:
- Length字段,2个byte,应设置为0x0009
- Type字段,1个byte,应设置为0x04
- Discardable Flag,1个bit,应设置为0
- Bit1到Bit7是保留位,全部为0
- IPv4-Address字段,4个byte,服务实例所在的主机的IPv4地址
- Reserved,1个byte,设置为0x00
- Transport Protocol字段,1个byte,传输层协议,0x06是TCP,0x11是UDP
- Transport Protocol Port Number,2个byte,传输层端口
“ 服务器应使用带有Offer Service Entries的IPv4端口Option来向其提供服务的端口发出信号。即最多一个UDP端口和一个TCP端口
”
“ 服务器使用Offer Service Entry引用的端口也被用来作为事件源。即端口选项中传输协议的源IP地址和源端口号
”
“ 客户端应使用带有Subscribe Eventgroup Entries的IPv4端口Option来通知IP地址和UDP和/或TCP端口号,在这些端口号上它已准备好接收事件
”
IPv6 Endpoint Option
IPv6端口Option被SOME/IP-SD实例用于向相关端口发出信号。端口包括本地IP地址、传输层协议(例如UDP或TCP)以及发送方的端口号。这些端口也用于事件和通知事件
IPv6端口Option的格式如下:
- Length字段,2个byte,应设置为0x0015
- Type字段,1个byte,应设置为0x06
- Discardable Flag,1个bit,应设置为0
- Bit1到Bit7是保留位,全部为0
- IPv6-Address,16个byte,服务实例所在的主机的IPv6地址
- Reserved,1个byte,设置为0x00
- Transport Protocol,1个byte,传输层协议,0x06是TCP,0x11是UDP
- Transport Protocol Port Number,2个byte,传输层端口
“ 服务器应使用带有Offer Service Entries的IPv6端口选项来向端口发出服务可用的信号。即最多一个UDP端口和一个TCP端口
”
“ 服务器使用一个Offer Service Entry引用的端口也被用来作为事件源。即端口选项中传输协议的源IP地址和源端口号
”
“ 客户端应使用带有Subscribe Eventgroup Entries的IPv6端口选项来通知IP地址和UDP和/或TCP端口号,它已准备好接收事件
”
IPv4 Multicast Option
服务器使用IPv4多播Option来宣布IPv4多播地址、传输层协议(ISO/OSI第4层)以及多播事件和多播通知事件发送到的端口号。作为传输层协议,目前仅支持UDP
“ IPv4多播选项应由Subscribe Eventgroup Ack Entries引用
”
“ IPv4多播选项应使用类型0x14
”
“ IPv4多播选项应指定IPv4地址、使用的传输层协议(ISO/OSI第4层)及其端口号
”
IPv4多播Option的格式如下:
- Length字段,2个byte,应设置为0x0009
- Type字段,1个byte,应设置为0x14
- Discardable Flag,1个bit,设置为0
- Bit1到Bit7是保留位,全部为0
- IPv4-Address,4个byte,本地多播地址
- Reserved,1个byte,设置为0x00
- Transport Protocol,1个byte,传输层协议,0x11是UDP
- Transport Protocol Port Number,2个byte,传输层端口
服务器应引用对IPv4多播地址和端口号进行编码的IPv4多播选项。而这个IPv4多播地址和端口号,是服务器发送多播事件和通知事件的地址和端口号
IPv6 Multicast Option
服务器使用IPv6多播Option来宣布IPv6多播地址、第4层协议以及多播事件和多播通知事件发送到的端口号。对于传输层协议(ISO/OSI第4层),目前仅支持UDP
“ IPv6多播选项应使用类型0x16
”
“ IPv6多播选项应指定IPv6地址、使用的传输层协议(ISO/OSI第4层)及其端口号
”
IPv6多播Option的格式如下:
- Length字段,2个byte,应设置为0x0015
- Type字段,1个byte,应设置为0x16
- Discardable Flag,1个bit,设置为0
- Bit1到Bit7是保留位,全部为0
- IPv6-Address,8个byte,本地多播地址
- Reserved,1个byte,设置为0x00
- Transport Protocol,1个byte,传输层协议,0x11是UDP
- Transport Protocol Port Number,2个byte,传输层端口
“ Subscribe Eventgroup Ack消息应引用IPv6多播选项而不是IPv6端口选项
”
“ 服务器应引用对IPv6多播地址和端口号进行编码的IPv6多播选项。而这个IPv6多播地址和端口号,是服务器发送多播事件和通知事件的地址和端口号
”
IPv4 SD Endpoint Option
IPv4 SD端口Option用于传输发送方SD实现的端口(即IP地址和端口)。即使在无法使用IP地址和/或端口号的情况下,这也可用于识别SOME/IP-SD实例
“ IPv4 SD端口选项在任何SD消息中最多出现1次
”
“ 仅当SOME/IP-SD消息通过IPv4传输时,才应包括IPv4 SD端口选项
”
“ IPv4 SD端口Option是Options Array中的第一个选项(如果存在)
”
“ 任何SD Entry都不应引用IPv4 SD端口选项
”
“ 如果IPv4 SD端口选项包含在SD消息中,则接收方应使用此选项的内容,而不是源IP地址和源端口
”
这对于回答接收到的SD消息(例如,在Find后Offer或在Offer后Subscribe或在Subscribe后Subscribe Ack)以及重新启动检测(基于SD端口Option而不是输出地址的通道)非常重要
“ IPv4 SD端口选项应使用类型0x24
”
“ IPv4 SD端口选项应指定用于服务发现的发送方的IPv4地址、传输层协议(ISO/OSI第4层)和端口号
”
IPv4 SD端口Option的格式如下:
- Length字段,2个byte,应设置为0x0015
- Type字段,1个byte,应设置为0x24
- Discardable Flag,1个bit,应设置为0
- Bit1到Bit7是保留位,全部为0
- IPv4-Address,4个byte,SOME/IP-SD的单播地址
- Reserved,1个byte,设置为0x00
- Transport Protocol,1个byte,SOME/IP-SD使用的传输层协议,0x11为UDP
- Transport Protocol Port Number,2个byte,SOME/IP-SD使用的传输层端口号,目前使用30490
IPv6 SD Endpoint Option
IPv6 SD端口Option用于传输发送方SD实现的端口(即IP地址和端口)。即使在无法使用IP地址和/或端口号的情况下,这也可用于识别SOME/IP-SD实例
“ IPv6 SD端口选项在任何SD消息中最多出现1次
”
“ IPv6 SD端口Option应是Option Array中的第一个选项(如果存在)
”
“ 任何SD Entry都不应引用IPv6 SD端口选项
”
“ 如果IPv6 SD端口选项包含在SD消息中,则接收方应使用此选项的内容而不是源IP地址和源端口来回答此SD消息
”
“ IPv6 SD端口选项应使用类型0x26
”
“ IPv6 SD端口选项应指定用于服务发现的发送方的IPv6地址、传输层协议(ISO/OSI第4层)和端口号
”
IPv6 SD端口Option的格式如下:
- Length字段,2个byte,应设置为0x0015
- Type字段,1个byte,应设置为0x26
- Discardable Flag,1个bit,应设置为0
- Bit1到Bit7是保留位,全部为0
- IPv6-Address,8个byte,SOME/IP-SD的单播地址
- Reserved,1个byte,设置为0x00
- Transport Protocol,1个byte,SOME/IP-SD使用的传输层协议,0x11是UDP
- Transport Protocol Port Number,2个byte,SOME/IP-SD使用的传输层端口号,目前使用30490
5.1.2.5 服务条目
Find Service Entry
Find Service Entry类型用于查找服务实例,并且仅在服务的当前状态未知时才发送(没有接收到当前的Service Offer并且仍然有效)
Find Service Entry应按以下方式设置Entry字段:
- Type应设置为0x00(表示Find Service)
- 服务ID应设置为想找到的服务的服务ID
- 如果想查找所有服务实例,则实例ID应设置为0xFFFF。如果只返回单个服务实例,则应设置为此服务实例的Instance ID
- Major Version应设置为0xFF,即返回任何版本的服务。如果设置为不同于0xFF的值,则应仅返回具有此特定主要版本的服务
- Minor Version应设置为0xFFFF FFFF,这意味着应返回任何版本的服务。如果设置为不同于0xFFFF FFFF的值,则应仅返回具有此特定次要版本的服务
- TTL应设置为Find Service Entry的生命周期。在此生命周期之后,Find Service Entry将被视为不存在
- 如果TTL设置为0xFFFFFF,则Find Service Entry直到下一次重新启动都将被视为有效
- TTL不能设置为0x000000
“ 发送方不得在Find Service Entry中引用端口选项或多播选项
”
“ 接收方应忽略Find Service Entry中的Endpoint Options和Multicast Options
”
“ 其他选项(既不是端口也不是多播选项),仍应允许在Find Service Entry中使用
”
“ 当接收到Find Service Entry时,服务ID、实例ID、主要版本和次要版本应与配置的值完全匹配以识别服务实例,除非Entry中有“任何值”(例如服务ID为0xFFFF,实例ID为0xFFFF,主要版本为0xFF,次要版本为0xFFFFFFFF)
”
Offer Service Entry
Offer Service Entry类型用于向其他通信伙伴提供服务
Offer Service Entry应按以下方式设置Entry字段:
- Type应设置为0x01(表示Offer Service)
- 服务ID应设置为提供的服务实例的服务ID
- Instance ID应设置为提供的服务实例的Instance ID
- Major Version应设置为提供的服务实例的主要版本
- Minor Version应设置为提供的服务实例的次要版本
- TTL应设置为服务实例的生命周期。在此生命周期之后,服务实例将被视为未提供
- 如果TTL设置为0xFFFFFF,则Offer Service Entry直到下一次重新启动都应被视为有效
- TTL不应设置为0x000000,因为这被认为是停止Offer Service Entry
“ Offer Service Entry应始终至少引用一个IPv4或IPv6端口选项,以表明服务如何可达
”
“ 对于服务所需的每个传输层协议(即UDP和/或TCP),如果支持IPv4,则应添加IPv4端口选项
”
“ 对于服务所需的每个传输层协议(即UDP和/或TCP),如果支持IPv6,则应添加IPv6端口选项
”
“ 当接收到初始的Offer Service Entry时,服务ID、实例ID、主要版本和次要版本应与配置的值完全匹配以识别服务实例,除非在服务配置中有“任何值”(例如0xFFFF用于实例ID,0xFFFFFFFF次要版本)
”
“ 当接收到后续的Offer Service Entry或Stop Offer Service Entry时,服务ID、实例ID、主要版本应与初始Offer Service Entry中的值完全匹配,以识别服务实例
”
Stop Offer Service Entry
“ Stop Offer Service Entry类型用于停止提供服务实例
”
“ Stop Offer Service Entry应设置与它们正在停止的Offer Service Entry完全相同的Entry字段,除了:TTL应设置为0x000000
”
Usage of Options in Entries
5.1.2.6 服务和事件的端口处理
“ 如果静态配置的值与这些选项中的值不同,则SD应使用在端口和多播选项中传输的IP地址和端口号重写
”
“ 端口选项的IP地址和端口号也用于传输事件和通知事件
”
“ 在UDP的情况下,端口选项用于作为事件和通知事件的源地址和源端口,也是客户端能够向其发送方法请求的地址
”
“ 在TCP的情况下,端口选项用于作为客户端需要打开TCP连接的IP地址和端口,以使用TCP接收事件
”
“ SOME/IP应允许服务同时使用UDP和TCP
”
“ 哪个消息由哪个底层传输协议发送由配置决定:一个Service可以同时使用UDP和TCP端口。但是无论使用TCP还是UDP,每个服务元素都应该配置
”
需要在配置中限制通过TCP/UDP提供哪些方法和哪些事件。这也意味着不能通过TCP和UDP提供相同的事件
Service Endpoints
Offer Service Entries引用的端口选项表示:
- 服务实例在服务器上可访问的IP地址和端口号
- 服务实例发送事件的源IP地址和源端口号
“ 除了Offer Service Entries的端口选项中给出的端口之外,该服务实例的事件不得从任何其他端口发送
”
“ 如果一个ECU提供多个服务实例,这些服务实例的SOME/IP消息应通过Offer Service Entries引用的端口选项中传输的信息来区分
”
Eventgroup Endpoints
“ Subscribe Eventgroup Entries中引用的端口选项也用于此服务实例的发送单播UDP或TCP SOME/IP事件
”
因此,Subscribe Eventgroup Entries中引用的端口选项是客户端的IP地址和端口号
“ 在发送Subscribe Eventgroup Entry之前,TCP事件使用客户端打开到服务器的TCP连接进行传输
”
“ 初始事件应使用单播从服务器传输到客户端
”
“ Subscribe Eventgroup Ack Entries最多引用1个使用Internet协议(IPv4或IPv6)的多播选项
”
“ 多播选项设置UDP作为传输协议
”
“ 客户端应尽快打开Subscribe Eventgroup Ack Entry引用的多播选项中指定的端口,以免错过多播事件
”
下图显示了具有不同端口和多播选项的示例:
- 服务器在服务器的UDP端口SU和服务器的TCP端口ST提供服务实例
- 客户端打开TCP连接
- 客户端发送带有客户端UDP端口CU(单播)和客户端TCP端口CT的Subscribe Eventgroup Entry
- 服务器以Multicast MU的Subscribe Eventgroup Ack Entry进行应答 然后发生以下操作:
- 客户端调用服务器上的方法
- CU向SU发送请求,SU向CU发送响应
- 对于TCP,这将是:向ST请求dyn和从ST到CT发送响应
- 服务器发送单播UDP事件:SU到CU
- 服务器发送单播TCP事件:ST到CT
- 服务器发送多播UDP事件:SU到MU
请记住,多播端口在接收方使用多播IP地址,而TCP不能用于多播通信
4.1.3 服务发现消息
所有服务发现消息都应发送到SD_PORT,SD_PORT用于服务发现单播/多播消息的源端口,所有单播SD消息都应将SD_PORT作为目标端口,除非SD端口Option定义了不同的端口,所有SD多播消息都应使用SD_MULTICAST_IP发送。
4.1.3.1 事件组条目
Subscribe Eventgroup Entry
Subscribe Eventgroup Entires 按以下方式设置Entry字段:
- Type设置为0x06(SubscribeEventgroup)
- Service ID应设置为包含订阅的事件组的服务实例的服务ID
- Instance ID应设置为包含订阅的事件组的服务实例的实例ID
- Major Version应设置为订阅的事件组的服务实例的主版本
- Eventgroup ID应设置为订阅的事件组的事件组ID
- TTL应设置为订阅的生命周期
- 如果设置为0xFFFFFF,则Subscribe Eventgroup Entry应被视为有效,直到下一次重新启动
- TTL不应设置为0x000000,因为这被认为是Stop Offer Service Entry
- Reserved应设置为0x00,直至另行通知
- 如果客户端按顺序发送第一个订阅以触发初始事件的发送,则初始数据请求标志应设置为1,否则设置为0
- Reserved2 应设置为三个0 bit位
- Counter用于区分并行订阅同一服务的同一事件组(仅端口不同)。如果不使用,设置为0x0
“Subscribe Eventgroup Entries引用最多两个IPv4或最多两个IPv6端口选项(一个用于UDP,一个用于TCP)”
如果服务器仅使用IP多播通过UDP传输事件,则 Subscribe Eventgroup Entry不需要引用UDP端口选项。如果服务器传输事件组的初始事件,则 Subscribe Eventgroup Entry应引用相应的端口选项,因为
“ 当接收到SubscribeEventgroup或StopSubscribeEventgroup时,服务ID、实例ID、事件组ID和主要版本应与配置的值完全匹配,以标识服务实例的事件组
”
“ 如果服务器接收到没有UDP端口选项的Subscribe Eventgroup Entry,并且事件组的MulticastThreshold未配置为值1,则应将SubscribeEventGroupNack发送回客户端
”
Stop Subscribe Eventgroup Entry
Stop Subscribe Eventgroup Entry类型应用于停止订阅事件组
Stop Subscribe Eventgroup Entries应设置与它们正在停止的订阅事件组Entry完全相同的Entry字段,除了:TTL设置为0x000000
Stop Subscribe Eventgroup Entry应引用与Subscribe Eventgroup Entry引用的相同Options。这包括但不限于端口和配置选项
Subscribe Eventgroup Acknowledgement (Subscribe Eventgroup Ack) Entry
Subscribe Eventgroup Acknowledgment Entry类型用于指示Subscribe Eventgroup Entry已被接受,Subscribe Eventgroup Acknowledgment Entry应按以下方式设置Entry字段:
- Type设置为0x07(SubscribeEventgroupAck)
- 服务ID、实例ID、主要版本、事件组ID、TTL、Reserved、Initial Data Requested Flag、Reserved2和Counter应与正在回答的订阅事件组中的值相同
引用通过多播传输的事件和通知事件的Subscribe Eventgroup Ack Entries应引用IPv4多播选项和/或IPv6多播选项。
当接收到SubscribeEventgroupAck或SubscribeEventgroupNack时,Service ID、Instance ID、Eventgroup ID和Major Ver-sion应与对应的SubscribeEventgroup Entry完全匹配,以标识Service Instance的Eventgroup
Subscribe Eventgroup Negative Acknowledgement (Subscribe Eventgroup Nack) Entry
Subscribe Eventgroup Negative Acknowledgment Entry类型应用于指示Subscribe Eventgroup Entry未被接受。
Subscribe Eventgroup Negative Acknowledgment Entries应按以下方式设置条目字段:
- Type设置为0x07(SubscribeEventgroupAck)
- Service ID, Instance ID, Major Version, Eventgroup ID, Counter和Reserved应与正在回答的订阅中的值相同
- TTL设置为0x000000
不接受订阅事件组的原因包括(但不限于):
- 服务ID、实例ID、事件组ID和主要版本的组合未知
- 客户端未打开所需的TCP连接
- 引用的Option出现问题
- 服务器上的资源问题
当客户端在需要TCP连接的SubscribeEventgroup上收到SubscribeEventgroupNack作为应答时,客户端应检查TCP连接并在需要时重新启动TCP连接
服务器可能丢失了TCP连接,而客户端没有
检查TCP连接可能包括以下内容:
- 检查是否收到数据,例如:其他事件组
- 发送Magic Cookie消息并等待TCP ACK
- 重新建立TCP连接
4.1.4 服务发现的通信行为
SOME/IP Service Discovery通过将Entries打包在一起来减少服务发现消息的数量。例如:
- 不同服务实例的多个Entries
- 不同类型的多个条目(例如,Offer entries、answers of Subscribed EventGroup entries)
4.1.4.1 启动行为(startup behavior)
对于每个服务实例,Service Discovery 在发送Entries方面至少应具有以下三个阶段:
- 初始等待阶段
- 重复阶段
- 主要阶段
实际的已实现的状态机将不仅仅需要这三个阶段的状态。例如, 本地服务可能仍处于关闭状态,而远程服务可能已经知道(不再需要查找)
“ 当此服务实例所需的接口上的链接已启动并且应用程序请求客户端服务时,Service Discovery应进入客户端服务实例的初始等待阶段
”
“ 当该服务实例所需的接口上的链接已启动且服务器服务可用时,Service Discovery应进入该服务器服务实例的初始等待阶段
”
链接可能已建立,但服务器端的服务尚不可用
系统已启动在这里表示所需的应用程序以及可能的外部传感器和执行器。基本上,此服务实例所需的功能必须准备好提供服务,并且在某些应用程序需要它之后找到服务是适用的
“ Service Discovery在进入初始等待阶段之后,在为服务实例发送第一条消息之前,将根据INITIAL_DELAY等待
”
“ INITIAL_DELAY应定义为最小和最大延迟
”
“ 等待时间应通过在INITIAL_DELAY的最小值和最大值之间选择一个随机值来确定
”
“ 如果ClientService和ServerService分别引用相同的ClientServiceTimer和ServerServiceTimer,并且它确保分别在同一时间点请求和释放引用的ClientServiceS和ServerServiceS,则服务发现应使用相同的随机值
”
“ 如果ClientServices和ServerService分别引用它们自己的ClientServiceTimer和ServerServiceTimer,则服务发现应为每个ClientService和ServerService使用不同的随机值。因此,如果ClientService或ServerSerivce进入初始等待阶段,它们将在初始等待阶段使用单独计算的随机值
”
“ 发送第一条消息后,进入此服务实例/这些服务实例的重复阶段
”
“ Service Discovery将根据REPETITIONS_BASE_DELAY在重复阶段等待
”
“ 在重复阶段发送每条消息后,延迟加倍
”
“ 服务发现在重复阶段只能发送最多REPETITIONS_MAX个entries
”
“ 在收到相应的Offer entries后,通过跳转到不发送Find entries的Main阶段停止发送Find entries
”
“ 如果REPETITIONS_MAX设置为0,则应跳过重复阶段,并在初始等待阶段后进入服务实例的主阶段
”
“ 在重复阶段之后,进入服务实例的主要阶段
”
“ 进入Main阶段后,提供者需要等待1CYCLIC_OFFER_DELAY才能发送第一个offer entry消息
”
“ 如果配置了CYCLIC_OFFER_DELAY,则在主阶段Offer消息应循环发送
”
“ 在发送指定的服务实例的消息后,Service Discovery会等待1CYCLIC_OFFER_DELAY,然后再发送此服务实例的下一条消息
”
“ 对于Find Entries(Find Service和Find Eventgroup),主阶段中不允许出现循环消息
”
“ Subscribe EventGroup Entries应由循环发送的Offer Entries触发"
例如:
初始等待阶段:
在(INITIAL_DELAY_MIN, _MAX)范围内中等待random_delay
发送消息(Find Service和Offer Service Entries)
重复阶段(REPETITIONS_BASE_DELAY=100ms,REPETITIONS_MAX=2):
-
等待 2 0 ∗ 100 m s 2^{0}*100ms 20∗100ms
-
发送消息(Find Service和Offer Service Entries)
-
等待 2 1 ∗ 100 m s 2^{1}*100ms 21∗100ms
-
发送消息(Find Service和Offer Service Entries)
主阶段(只要消息处于活动状态并且定义了CYCLIC_OFFER_DELAY): -
等待CYCLIC_OFFER_DELAY
-
发送消息(Offer Service Entries)
4.1.4.2 服务端回复行为
Service Discovery应使用配置项REQUEST_RESPONSE_DELAY延迟回答在多播SOME/IP-SD消息中接收到的Entries。这适用于以下两种情况:
- 在收到Find Entry(多播)后Offer Entry(单播或多播)
- 在收到Offer Entry(多播)后Subscribe Entry(单播)
“ 如果用单播消息回答单播消息,则REQUEST_RESPONSE_DELAY将不适用
”
“ REQUEST_RESPONSE_DELAY应由最小值和最大值指定
”
“ 实际延迟应在REQUEST_RESPONSE_DELAY的最小值和最大值之间随机选择
”
“ 对于基本实现,所有Find Service Entries都应通过使用单播传输的Offer Service Entries来回答 "
出于优化目的,应支持以下行为作为选项:
- 在主阶段接收到的Unicast Flag设置为1的Find消息,如果最后一个Offer是在不到1/2 CYCLIC_OFFER_DELAY之前发送的,则应使用单播响应来回答
- 如果最后一个Offer是在1/2 CYCLIC_OFFER_DELAY或更早之前发送的,则在主阶段接收到的Unicast Flag设置为1的Find消息应使用多播响应来回答
- 应忽略Unicast Flag设置为0(多播)的Find消息
4.1.4.3 关机行为
“ 当ECU的服务器服务实例处于重复和主阶段并正在停止时,应发出Stop Offer Service Entry
”
“ 当一个服务器服务实例在初始等待阶段、重复阶段或主阶段链路断开时,当链路再次启动且服务仍然可用时,Service Discovery将进入初始等待阶段
”
“ 当客户端服务实例在初始等待阶段、重复阶段或主阶段链路断开时,Service Discovery应在链路再次启动且仍请求服务时进入初始等待阶段
”
“ 当服务器发出Stop Offer Service Entry时,该服务实例的所有订阅都应在服务器端删除
”
“ 当客户端收到Stop Offer Service Entry时,该服务实例的所有订阅都应在客户端删除
”
“ 当客户端收到Stop Offer Service Entry时,客户端不应发送Find Service Entry,而是等待Offer Service Entry或状态更改(应用程序、网络管理、以太网链路或类似)
”
“ 当ECU的客户端服务实例处于主阶段并且正在停止(即服务实例被释放)时,SD应为所有订阅的事件组发送Stop Subscribe Eventgroup Entries
”
“ 当整个ECU被关闭时,所有的服务Entries应发送Stop Offer Service Entries,所有的事件组应发送Stop Subscribe Eventgroup Entries
”
4.1.4.4 状态机
SOME/IP Service状态机(服务器)如下图所示:
SOME/IP Service状态机(客户端)如下图所示:
4.1.4.5 SOME/IP-SD机制和错误
在本节中,讨论了错误情况下的SOME/IP-SD(例如丢失或损坏的数据包)。这也被理解为使用的机制和可能的配置的基本原理
软状态协议:SOME/IP-SD被设计为软状态协议,这意味着Entries具有生命周期,需要刷新才能保持有效(将TTL设置为最大值将关闭此功能)
初始等待阶段:
引入初始等待阶段有两个原因:启动ECU的去偏移事件以避免流量突发,并允许ECU收集SD消息中的多个entries
重复阶段:
引入了重复阶段以允许客户端和服务器的快速同步。如果客户端启动较晚,它会很快找到服务器。而且如果服务器稍后启动,可以很快找到客户端。重复阶段以指数方式增加两条消息之间的时间,以避免过载情况使系统无法同步
主阶段:
在主阶段,SD尝试稳定状态,从而通过不再发送查找服务来降低数据包速率,并且仅在循环间隔(例如每1秒)中提供
请求-响应-延迟:
SOME/IP-SD应配置为通过请求-响应-延迟来延迟对多播消息中entries的回答。这在具有许多ECU的大型系统中很有用。当发送一个包含许多entries的SD消息时,来自不同ECU的大量回复同时到达,并且对接收所有这些回复的ECU施加了很大的压力
4.1.4.6 错误处理
上图显示了对传入的SOME/IP-SD消息进行错误处理的简化过程
“ 检查是否存在用于空SOME/IP-SD消息的至少足够字节,即消息至少有12个字节长。如果检查失败,则该消息将被丢弃,无需进一步操作
”
“ 如果接收到的entry的服务ID未知,则应忽略该entry
”
“ 如果接收到的entry的实例ID未知,则应忽略该entry
”
“ 如果接收到的entry的主版本未知,则应忽略该entry
”
“ 如果接收到的entry的事件组ID未知,则应忽略该条目。这仅适用于事件组entry
”
“ 如果Entries数组的长度无效(即entries数组将超过消息大小),则应丢弃该消息,无需进一步操作
”
检查每个收到的Entry引用的选项:
- 引用的Options存在
- 该Entry引用了所有必需的Options(例如,提供的使用单播的事件组需要接收到的Subscribe Eventgroup Entry中的单播端口选项)
- 该Entry仅引用支持的Options(例如,不支持多播数据接收的所需事件组不支持Subscribe Eventgroup ACK Entry中的多播端口选项)
- Entry引用的Options之间不存在冲突(即两个相同类型的选项内容相互矛盾)
- 被引用选项的类型已知或可丢弃标志设置为1
- 被引用选项的类型被Entry允许或可丢弃标志设置为1
- 被引用选项的长度与选项的类型一致
- 端口选项具有有效的L4协议字段
- 该选项有效(例如,多播端点选项应使用多播IP地址)
如果Entry引用了SD已知但服务不需要的Option(例如,Offer引用TCP和UDP选项并且客户端仅使用UDP,或者Subscribe Eventgroup Entry引用UDP端口选项但服务器仅使用多播事件传输),则应处理该Entry
“ 检查TCP连接是否已经存在(仅适用于为事件组配置TCP并且收到 Subscribe Eventgroup Entry的情况)
”
“ 检查是否剩余足够的资源(例如套接字连接)
”
“ 如果对收到的Find entry的检查失败,则应忽略该entry
”
“ 如果对收到的Offer entry的检查失败,则该entry将被忽略
”
“ 如果对接收到的Subscribe Eventgroup Entry的检查失败,则应发送Subscribe Eventgroup NACK Entry
”
“ 如果对接收到的 Subscribe Eventgroup ACK Entry的检查失败,则应处理该entry,但不应将订阅视为成功
”
如果出现以下情况,Entry引用的选项将被忽略:
- 选项类型未知(即尚未指定,或接收方不支持)并且可丢弃标志设置为1
- 该选项是多余的(即该entry引用了另一个相同类型和相同内容的选项)
- 该选项不是必需的(例如,提供的仅使用多播的事件组在收到的Subscribe Eventgroup Entry中不需要单播端口选项,尽管它仍然是允许的)
4.1.5 使用SOME/IP-SD的非SOME/IP协议
除了SOME/IP之外,车内还使用了其他通信协议;例如,用于网络管理、诊断或闪存更新。此类通信协议可能需要与服务实例通信或还具有事件组
对于非SOME/IP协议(应用程序协议本身不使用SOME/IP,但它通过SOME/IP SD发布)应使用特殊的服务ID,并应使用配置选项添加更多信息:
- 服务ID应设置为0xFFFE(保留)
- 实例ID应按照SOME/IP服务和事件组的描述使用
- 应添加配置选项,并应包含一个带有键“otherserv”的Entry和一个由系统部门确定的可配置非空值
“ SOME/IP服务不应使用配置选项中的otherserv-string”
“ 对于Find Service/Offer Service/Request Service Entry,在宣布非SOME/IP服务实例时应使用otherserv-String”
4.1.6 Publish/Subscribe with SOME/IP and SOME/IP-SD
注意:与SOME/IP请求/响应机制相比,在某些情况下,客户端可能需要从服务器获得一组参数,但不希望每次需要时都请求该信息。它们被称为通知、关注事件和字段(Fields)。
“ 通过SOME/IP-SD Entry Offer Service,服务器提供向客户端推送通知;因此,它用作订阅的触发器
”
“ 只要客户端仍然有兴趣接收此事件组的通知/事件,每个客户端都应使用SOME/IP-SD Subscribe Eventgroup Entry响应来自服务器的SOME/IP-SD Offer Service Entry
”
“ 如果客户端能够使用SOME/IP-SD消息reboot flag可靠地检测到服务器的重新启动,则客户端可以选择仅在服务器重新启动后回复Offer Service消息(如果配置为这样做)(TTL设置为最大值)。即使服务器的SOME/IP-SD消息丢失,客户端也会确保其工作可靠
”
“ 如果客户端没有对事件组的有效订阅,则客户端应通过设置初始数据请求标志来明确请求初始事件
”
“ 如果客户端发送了额外的Subscribe Eventgroup Entries并且前一个订阅的TTL没有过期,那么客户端不应请求初始事件”
客户明确请求初始事件的原因包括但不限于:
- 客户端当前未订阅事件组
- 客户端在最后一个Subscribe Eventgroup Entry之后看到了链接断开/链接启动
- 客户端在最后一个常规订阅事件组之后没有收到订阅事件组确认
- 客户端检测到此服务的服务器重新启动
“ 如果客户端订阅了两个或多个事件组,包括一个或多个相同的事件或字段,则服务器不应为该字段发送重复的事件或通知事件。这意味着是常规事件而不是初始事件”
客户端链接丢失的发布/订阅描述如下:
-
没有事先注册+客户端订阅
(a) Server: OfferService()
(b) Client: SubscribeEventgroup[Session ID=x, Reboot=0]
© Server: updateRegistration()
(d) Server: SubscribeEventgroupAck + Events() -
客户端链路丢失
(a) Client: linkDown()
(b) Client: deleteEntries()
© Client: linkUp()
- 客户端再次订阅,检测到客户端重启
(a) Server: OfferService()
(b) Client: SubscribeEventgroup[Session ID=1, Reboot=1]
© Server: updateRegistration()
(d) Server SubscribeEventgroupAck + Events()
客户端应通过发送TTL=0的SOME/IP-SD订阅事件组消息(停止订阅事件组)从服务器注销
发布/订阅,注册/注销行为描述如下:
- Client 1 subscribes
(a) Server: OfferService() to Client 1 and Client 2
(b) Client 1: SubscribeEventgroup()
© Server: updateRegistration()
(d) Server: SubscribeEventgroupAck + Events() to Client 1 - Client 2 subscribes
(a) Client 2: SubscribeEventgroup()
(b) Server: updateRegistration()
© Server: SubscribeEventgroupAck + Events() to Client 2 - Client 2 stops subscription
(a) Client 2: StopSubscribeEventgroup()
(b) Server: updateRegistration() - Client 1 remains registered
如果在发送事件或通知事件后发生相关的SOME/IP错误,服务器上的SOME/IP-SD将删除订阅,错误包括但不限于无法到达通讯伙伴和TCP连接错误
服务器上链接丢失的发布/订阅描述如下:
- No prior registrations + Client subscribes
(a) Server: OfferService()
(b) Client: SubscribeEventgroup()
© Server: updateRegistration()
(d) Server: SubscribeEventgroupAck + Events() - Link loss at server side
(a) Client: linkDown()
(b) Client: deleteRegistrations()
© Client: linkUp() - Server offers again, Server Reboot detected by client
(a) Server: OfferService()[Session ID=1, Reboot=1]
(b) Client: SubscribeEventgroup()
© Server: updateRegistration()
(d) Server SubscribeEventgroupAck + Events()
“ 如果通过TCP提供服务并且客户端根据配置通过TCP请求事件组,则客户端应在发送Subscribe Eventgroup Entry之前打开与服务器的TCP连接
”
“ 客户端发送Subscribe Eventgroup Entry后,服务器应发送Subscribe Eventgroup Ack Entry
”
客户端应等待确认Subscribe Eventgroup Entry的Subscribe Eventgroup Ack Entry。如果在发送下一个Subscribe Eventgroup Entry之前该Subscribe Eventgroup Ack Entry未到达,则客户端应执行以下操作:
如果服务器的“显式初始数据控制标志”设置为0,则在发送Subscribe Eventgroup Entry的同一SOME/IP-SD消息中发送Stop Subscribe Eventgroup Entry和Subscribe Eventgroup Entry
如果“服务器的显式初始数据控制标志设置为1”,则将下一个Subscribe Eventgroup Entry的初始数据请求标志设置为1
这种行为的存在是为了应对短时间的通信丢失,因此会触发新的初始事件以降低消息丢失的影响
如果客户端发送一个订阅事件组Entry作为对单播Offer的反应,并且在此之后但在订阅事件组确认entry可以由服务器发送和接收之前立即到达多播Offer,则客户端不应抱怨(例如停止订阅/订阅) 关于尚未收到的确认
存在这种行为是为了应对短时间的通信丢失。停止订阅事件组和订阅事件组组合的接收者将发送初始事件以降低消息丢失的影响
“ 如果初始值值得关注 - 例如对于字段 - 并且客户端将显式初始数据控制标志(在SOME/IP-SD首部中)设置为0,则服务器在发送订阅事件组确认后应立即发送第一个通知/事件(即初始事件)
”
“ 如果服务器接收到初始数据请求标志设置为0且显式初始数据控制标志(在SOME/IP-SD首部中)设置为1的Subscribe Eventgroup Entry,则服务器将不发送通知/事件(即初始事件)
”
“ 如果服务器接收到初始数据请求标志设置为1且显式初始数据控制标志(在SOME/IP-SD首部中)设置为1的订阅事件组Entry,则服务器在发送订阅事件组确认后应立即发送通知/事件(即初始事件)
”
“ 订阅时不允许发送事件的初始值(纯事件而非字段)
”
“ 字段通知器的事件消息应在订阅上发送(字段而不是纯事件)
”
“ 如果订阅已经有效并且由订阅事件组Entry更新,则不应发送初始事件
”
“ 接收Stop Subscribe/Subscribe组合触发字段通知的初始事件
”
“ 初始事件应在订阅事件组确认之后发送"
发布/订阅状态(单播事件组的服务器行为)定义如下:
“ 如果客户端使用不同的SOME/IP-SD消息订阅同一服务实例的不同事件组,并且所有事件组包含相同的字段,则服务器应为每个订阅分别发送该字段的初始事件
”
“ 如果客户端使用一条SOME/IP-SD消息订阅同一服务实例的不同事件组,并且所有事件组都包含相同的字段,则服务器可以选择不多次发送该字段的初始事件
”
这意味着服务器可以通过仅发送一次初始事件来优化,如果其架构支持的话
发布/订阅状态(多播事件组的服务器行为)定义如下:
服务端自适应单播/组播事件组行为的发布/订阅状态时序图如下:
“如果达到了用户数量的配置阈值,SOME/IP-SD应支持从单播到多播的自动切换”
“SOME/IP SD协议应支持通信端口的隐式配置和订阅者的注册。这些应基于静态配置,并且不使用网络上的任何SD消息”
以下entries应仅通过单播传输:
- 订阅事件组
- 停止订阅事件组
- 订阅事件组确认
- 订阅事件组否定确认
“ 如果SUBSCRIBE_RETRY_MAX配置为大于0,客户端应重试订阅 ServerService的Eventgroup。如果在可配置的超时(SUBSCRIBE_RETRY_DELAY)内未收到请求的Eventgroup的SubscribeEventgroupAck/NAck entry,则应发送对Eventgroup 的订阅)。只要请求事件组并且未超过配置的重试计数(SUBSCRIBE_RETRY_MAX),就应进行重试
”
“ 接收到的OfferService的TTL设置为0xFFFFFF的ServerService,可以将SUBSCRIBE_RETRY_MAX设置为INF。在这种情况下,只要请求了Eventgroup并且没有收到请求的Eventgroup的SubscribeEventgroupAck/NAck entry,就应该进行重试
4.1.7 SOME/IP和SOME/IP-SD的保留和特殊标识符
本章节主要介绍保留标识符和特殊标识符
5. 配置参数
Name | Description |
---|---|
INITIAL_DELAY_MIN | Minimum duration to delay randomly the transmission of a message. |
INITIAL_DELAY_MAX | Maximum duration to delay randomly the transmission of a message. |
REPETITIONS_BASE_DELAY | Duration of delay for repetitions. |
REPETITIONS_MAX | Configuration for the maximum number of repetitions. |
REQUEST_RESPONSE_DELAY | The Service Discovery shall delay answers using this configuration item. |
CYCLIC_OFFER_DELAY | Interval between cyclic offers in the main phase. |
SD_PORT | is a UDP Port for SD Messages (30490 as default). |
SD_MULTICAST_IP | address which shall be used by the SD multicast messages. |
SUBSCRIBE_RETRY_MAX | Max count of retries for subscribe, as long as the Event-group is requested (0=no retry, INF= retry forever (as long as the Eventgroup is requested and no no SubscribeEventgroupAck/Nack entry was received)). |
SUBSCRIBE_RETRY_DELAY | Duration of delay to send a consecutive subscribe entries, if a Eventgroup is requested and no SubscribeEventgroupAck/Nack entry was received. |
MULTICAST_THRESHOLD | Specifies the number of subscribed clients with different endpoint information per Eventgroup that triggers the server to change the transmission of events to the server service multicast endpoint. This multicast endpoint is configured by the server service and provided with the SubscribeEventgroupAck: - If configured to 0 only the client service unicast/-multicast endpoint will be used. - If configured to 1 the first client and all further subscribed clients will be served via the server service multicast endpoint. - If configured to n up to n-1 clients with different endpoint information will be served via a client service unicast/multicast endpoint provided by the client within the SubscribeEventgroup. As soon as the number of subscribed clients with different endpoint information reaches n, then all subscribed clients are served via the server service multicast endpoint. |
6 协议使用
6.1 SOME/IP-SD Options的安全注意事项
“ 接收到的SOME/IP-SD消息应检查端口选项和SD端口选项中接收的IP地址是拓扑正确的(参考使用SOME/IP-SD的IP子网中的 IP地址)并且应忽略不是拓扑正确的以及引用这些选项的entries
”
这意味着只能访问同一子集中的客户端和服务器
6.2 强制功能集和基本行为
在本节中,将讨论服务发现的强制性功能集和相关的配置约束。 这允许在没有当前用例可能不需要的可选的或信息化的功能的情况下进行最低限度的实现
以下信息被定义为合规检查清单。如果未实现某个功能,则认为该实现不符合SOME/IP-SDs基本功能集
应实现以下entry类型:
Find Service
Offer Service
Stop Offer Service
Subscribe Eventgroup
Stop Subscribe Eventgroup
Subscribe Eventgroup Ack
Subscribe Eventgroup Nack
当需要 IPv4 时,应实现以下option类型:
IPv4 Endpoint Option
IPv4 Multicast Option
Configuration Option
IPv4 SD Endpoint Option (receiving at least)
如果需要IPv6,应实现以下option类型:
IPv6 Endpoint Option
IPv6 Multicast Option
Configuration Option
IPv6 SD Endpoint Option (receiving at least)
以下行为/反应应在服务器端实现:
服务器应根据配置提供包括初始等待阶段、重复阶段和主要阶段的服务
服务器应在SD_MULTICAST_IP定义的多播地址上使用多播(重复阶段和主阶段)Offer Service
服务器不需要在重复阶段回答Find Service
服务器应使用单播(没有基于单播标志的优化)以Offer Serive来回答主阶段的Find Service
服务器在关闭时应发送停止Offer Serice
服务器应接收订阅事件组和停止订阅事件组,并根据本规范做出反应
服务器应使用单播发送订阅事件组确认和订阅事件组确认。
服务器应支持基于SOME/IP-SD的订阅控制SOME/IP事件消息的发送。这可能包括发送基于多播的事件
服务器应支持触发初始SOME/IP事件消息
以下行为/反应应在客户端实施:
客户端应仅在重复阶段使用查找服务entry和多播(在SD_MULTICAST_IP 定义的多播地址上)来Find Service
如果常规Offer Service到达,客户应停止Find Service
客户端应使用单播SD消息对服务器OfferService做出反应,该消息包括客户端当前想要订阅的服务器消息中提供的服务的所有订阅事件组
客户应按照本文档中的规定解释并响应订阅事件组确认和订阅事件组否定确认
客户端应支持以下行为和配置约束:
如果仅指定SD计时的TTL,则客户端应能够处理事件组。这意味着在初始等待阶段、重复阶段和主阶段的所有时序中,仅配置了TTL。这意味着客户端只能对服务器的Offer Service作出反应
即使没有配置Request-Response-Delay,客户也应使用订阅事件组响应Offer Service,这意味着它不应等待而是立即响应
客户端和服务器应实施本文档中指定的重启检测并做出相应反应。 这包括但不限于:
根据本规范设置会话ID和重启标志
保留仅用于发送多播SD消息的会话ID计数器
为每个单播关系保留会话ID计数器以发送单播SD消息
根据本规范了解会话ID和重启标志
为与该ECU交换多播SD消息的每个ECU保留一个多播会话ID计数器
为与该ECU交换单播SD消息的每个ECU保留一个单播会话ID计数器
根据此规范检测重启并做出相应反应
正确解释有关重启检测的IPv4和IPv6 SD端口选项
客户端和服务器应实现“服务和事件的端口处理”。这包括但不限于:
如果需要UDP,则将1个端口选项UDP添加到提供服务
如果需要TCP,则将1个端口选项TCP添加到提供服务
如果需要UDP事件,则将1个端口选项UDP添加到订阅事件组
如果需要TCP事件,则将1个端口选项TCP添加到订阅事件组
如果需要多播事件,则添加1个多播选项UDP到订阅事件组确认
根据上述传输的端口和多播选项了解和采取行动
使用这些端口和多播选项的信息覆盖预配置的值(例如IP地址和端口)
将传入的IPv4和IPv6端口选项解释为SD端口,而不是外层的地址和端口号
“ 客户端和服务器应实现对初始事件的显式请求
”
6.3 迁移和兼容性
6.3.1 支持同一服务的多个版本
为了支持迁移场景,ECU应支持服务以及使用同一服务的不同不兼容版本
为了支持具有多个版本的服务,需要以下内容:
服务器应为每个主要版本提供一次该服务的服务实例
客户端应在每个支持的主要版本中查找一次服务实例,或者应将主要版本用作0xFF(所有版本)
客户端应订阅它需要的服务版本的事件
所有SOME/IP-SD Entries应使用相同的服务ID和实例ID,但主要版本不同
服务器必须根据它们到达的套接字、消息ID、主要版本对消息进行多路分解,并根据这些条件在内部将其中继到正确的接收器
“ 在一个VLAN中,最多有一个Service ID、Major Version 和Instance ID相同的服务实例。这适用于服务器和客户端网络节点
”
不允许在一个网络节点上配置多个仅在次要版本上有所不同的服务实例,因为它们在事件组entries中无法区分
7. 参考
1.AUTOSAR_PRS_SOMEIPServiceDiscoveryProtocol
2. 详解SOME/IP-SD协议文档