这份协议规范规定了协议SOME/IP Service Discovery (SOME/IP-SD)的格式、消息序列和语义
服务发现协议的主要任务是在车载通信中传达功能实体(也就是服务)的可用性,以及控制事件消息的发送行为。这允许只发送事件消息给那些需要它们的接收者(发布/订阅),此处描述的解决方案也称为SOME/IP-SD(基于IP的可扩展的面向服务的中间件-服务发现)
可以看出,SOME/IP-SD有两个功能:
关于第2点,更详细点来说,是通过SOME/IP-SD对服务进行订阅,然后再用SOME/IP里的Notification类型消息发布订阅内容
SOME/IP-SD被用来
这里和上面的SOME/IP-SD的两个功能不矛盾,只是把上面第1点拆开成两个功能而已
SOME/IP SD可用于汽车网络中的服务发现
目前,SOME/IP-SD仅支持基于IP的通信
SOME/IP-SD依赖于SOME/IP。SOME/IP本身支持TCP和UDP通信,但SOME/IP SD被限制为只能通过UDP
为什么SOME/IP SD只能基于UDP通信?
我们知道,任何协议都有其特点,使用者根据自身需求选择合适的协议。TCP协议的特点是可靠性,UDP协议虽然不可靠但延时低,而且可以实现广播和组播。而SOME/IP SD要实现的功能就需要单播和多播
从上图看出,SOME/IP-SD消息前面封装的协议头部依次是SOME/IP、UDP和IP
这里列举了SOME/IP SD支持的功能依赖的其他需求,巴拉巴拉一堆
这里只举例一些我觉得重要的词语
缩略词 | 描述 |
---|---|
RPC | Remote Procedure Call,一个ECU用消息调用另一个ECU的函数接口,也叫远程调用 |
Request | 客户端向服务器发送调用方法的消息 |
Response | 服务器向客户端传输方法调用结果的消息 |
Request/Response communication | 一个由请求和响应组成的RPC |
Fire&Forget communication | 仅包含请求消息的RPC调用 |
Event | 单向数据传输,仅在更改或循环时调用,并从数据的生产者发送到消费者。一个事件甚至可以在变化时周期性地和自发地发送。这完全由发送应用程序负责,因为接收者根本无法区分这两者 |
Field | 一个字段代表了一个状态,因此在getter、setter和notfier所作用的任何时候都有一个有效的值 |
Getter | 允许对字段进行读取访问的请求/响应调用 |
Setter | 允许对字段进行写入访问的请求/响应调用 |
Notifier | 在字段值更改时发送具有新值的事件消息 |
Notification Event | 字段的notifier发送的事件消息。这种notifier的消息无法与Event消息区分开来;因此,当涉及到事件消息时,对于字段的notifier的消息也是一样的 |
Service | 零个或多个方法、零个或多个事件、零个或多个字段的逻辑组合(允许空服务,例如用于在SOME/IP-SD中宣布非SOME/IP服务) |
Eventgroup | 服务内部,Event和字段的notifier的逻辑分组,以允许订阅 |
Service Interface | 服务的正式规范,包括方法、事件和字段 |
Service Instance | 服务接口的软件实现,可以在车辆中多次存在,也可以在ECU中多次存在 |
Offering a service instance | 一个ECU实现了一个服务实例,并使用SOME/IP-SD告诉其他ECU,他们可以使用它,这指的是主动告知自己可用的服务有哪些 |
Finding a service instance | 发送SOME/IP-SD消息以找到所需的服务实例,这指的是询问对方有哪些服务可用 |
Requiring a service instance | 向正在执行所需服务实例的ECU发送SOME/IP-SD消息,这意味着其他ECU需要此服务实例,这指的是订阅服务 |
Releasing a service instance | 向托管此服务实例的ECU发送SOME/IP-SD消息,这意味着不再需要该服务实例,这指的是取消订阅 |
Publishing an eventgroup | 使用SOME/IP-SD消息向其他ECU提供服务实例事件组 |
Subscribing an eventgroup | 使用SOME/IP-SD消息订阅服务实例事件组 |
SOME/IP-SD被用来
车内网络服务实例位置众所周知;因此,服务实例的状态是首要关注的问题。服务的位置(即IP地址、传输协议和端口号)是次要的问题
这个状态指的应该是是否可用
如果需要在多个接口上提供服务实例,则每个接口应使用单独的服务器服务实例
如果需要将服务实例配置为使用多个不同的接口访问,则每个接口应使用单独的客户端服务实例
这里定义的是服务接口对应的服务实例,要如何实现
SOME/IP-SD消息应通过UDP发送
SOME/IP-SD首部格式如下:
可以看出,SOME/IP-SD消息是以SOME/IP首部开始,只是里面的几个字段是固定值
你也可以把它看成是特殊的SOME/IP消息,Payload部分包含SOME/IP-SD首部
- SOME/IP-SD消息应以SOME/IP首部开始
- SOME/IP-SD消息的Service ID为0xFFFF
- SOME/IP-SD消息的Method ID为0x8100
- SOME/IP-SD消息中SOME/IP首部里的Length字段,表示从Length字段后的第一个字节开始,到SOME/IP-SD消息的最后一个字节结束的长度
- SOME/IP-SD消息的Client ID设置为0x0000,因为只存在一个单独的SOME/IP-SD实例
- 如果配置了Client ID前缀,它也同样适用于SOME/IP-SD
- SOME/IP-SD消息应具有Session ID并根据SOME/IP要求进行处理
- 每发送一条SOME/IP-SD消息,都要增加Session ID的值
- Session ID应该从1开始
- Session ID不能设置为0
- SOME/IP-SD的Session ID的处理是按照“通信关系”完成的,即广播和单播作为一个配对
- SOME/IP-SD的Protocol Version应该为0x01
- SOME/IP-SD的Interface Version应该为0x01
- SOME/IP-SD的Message Type应该为0x02(Notification)
- SOME/IP-SD的Return Code应该为0x00(E_OK)
这里有几条需求需要拎出来分析:
由于只有一个单独的SOME/IP实例,所以就没必要设置Client ID,这说明并不是每个程序或服务都会发送一个自己的SOME/IP-SD消息
也就是说,一个Session ID的值,要表示一来一回这样的通信过程,发出去是什么值,响应的也要是什么值
下图是一条SOME/IP-SD消息的示例
从上图看出,SOME/IP-SD使用SOME/IP传输,首部是以Flags标志位开始
Flags字段的最高位称为Reboot标志
SOME/IP-SD Header的Reboot Flag应在重新启动后为所有消息设置为1,直到SOME/IP-Header中的Session-ID循环回来并再次以1开始。在循环回来后Reboot标志设置为0
Reboot Flag和Session ID的信息应该被多播和单播分别保存
Reboot Flag和Session ID的信息应该被每个发送方-接收方关系(即源地址和目的地址)分别保存
这意味着
发送方:
接收方:
reboot检测应按如下方式进行(使用来自通信伙伴的当前数据包的新值和之前接收到的旧值):
Flags字段的第二高位称为Unicast标志
对于所有SD消息,SOME/IP-SD报头的单播标志应设置为单播(即1),因为这意味着支持使用单播进行接收
单播标志是从历史SOME/IP版本遗留下来的,仅出于兼容性原因而保留。除此之外,它的使用非常有限
Flags字段的第三高位称为Explicit Initial Data Control标志,表示ECU支持显式初始数据控制,这意味着ECU理解并尊重事件组条目中的初始数据请求标志
显式初始数据控制标志应始终设置为1,这意味着ECU支持此功能
此标志允许与不支持此功能并将此标志设置为0的旧SOME/IP-SD 实现兼容。新版本应全部支持该功能,因此它们必须始终将此标志设置为1
发送时Flags字段中未定义bit位应设置为“0”,接收时忽略
在Flags字段后,有一个Reserved字段,24个bit
Reserverd字段后面就是SOME/IP-SD消息的两个重要的部分,一个是Entries Array,另一个是Options Array
Entry,很多文章中描述为“入口”,携带的信息是服务和服务实例,对于接收者来说,从这里“进入”获取服务实例位置和可用性
Option,是Entry的附加信息,比如IP地址等
Entries array应该按照到达的顺序准确处理
Entries Array和Options Array都是以一个Length字段开始,用来统计Entries Array和Options Array的字节数
SOME/IP-SD支持在一个SOME/IP-SD消息中组合多个Entry
这些Entries用于同步服务实例的状态和发布/订阅处理
Entry类型有两种:
用于服务的服务Entry类型
用于事件组的事件组Entry类型
服务Entry的大小为16个字节,按顺序包含以下字段:
事件组Entry的大小为16个字节,按顺序包含以下字段:
支持两个Option运行的基本原理:
需要两种不同类型的Option:多个SOME/IP-SD Entry之间的通用Option和每个SOME/IP-SD Entry不同的Option。支持两种不同的Option运行是支持这两种类型的Option的最有效方式
也就是说Option分两类,一类是Entry共用的,一类是每个Entry自己的,这也就是为什么Entry中会存在First Option和Second Option
Entry中First Option和Second Option的运行参考的是索引和数量
如果Option数量设置为0,则Option运行被视为空
对于空运行,索引(Index First Option Run and/or Index Second Option Run)为0
Options用于将附加信息传输给Entries“入口”,包括例如如何访问服务实例的信息(IP地址、传输协议、端口号)
为了识别Option类型,每个Option都应以下面字段开始:
Length字段表示该Option除了Length字段和Type字段外的所有字节数
如果接收方ECU不支持该Option,且可以丢弃它,那么Discardable Flag应该设置为1
Option类型有如下:
配置Option用于传输任意的配置字符串,这允许对附加信息进行编码,例如服务名称或是它的配置
配置Option的格式如下:
配置选项应指定一组基于DNS TXT和DNS-SD格式的"名称-值"对
配置字符串的格式应以单个字节长度字段开始,该字段描述该长度字段之后的字节数。在长度字段之后应遵循具有指定长度的字符序列
在每个字符序列之后,期望另一个长度字段和随后的字符序列,直到长度字段应设置为0x00
将长度字段设置为0x00后,不得跟随任何字符
一个字符序列应该编码一个键和一个可选的值
字符序列应包含一个相等的字符(“=”,0x3D)来划分键和值
键不应包含相等的字符,并且应至少是一个非空白字符。“Key”的字符应为可打印的US ASCII值(0x20-0x7E),不包括‘=’(0x3D)
“=”不应是序列的第一个字符
对于没有“=”的字符序列,该键应被解释为存在
对于以“=”结尾的字符序列,该键应被解释为具有空值
应支持在单个配置选项中具有多个相同键的条目
配置Option的格式为:
负载平衡Option用于区分服务的不同实例的优先级,以便客户端根据这些设置选择服务实例。此Option附加在Offer Service Entries的后面
负载平衡选项应携带与DNS-SRV记录类似的优先级和权重,用于对不同服务实例进行负载平衡
在查找服务的所有服务实例时(服务实例设置为0xFFFF),客户端应选择具有最高优先级且也符合客户端特定标准的服务实例
当有多个具有最高优先级(Priority字段中的最低值)的服务实例时,应根据服务实例的权重随机选择服务实例。选择服务实例的概率应为服务实例的权重除以所有考虑的服务实例的权重之和
如果一个Offer Service Entry没有引用负载平衡选项并且提供了多个服务实例,则客户端应按照最低优先级处理没有负载平衡选项的服务实例
在查找某个服务的特定服务实例时(Service Instance设置为0xFFFF以外的任何值),Load Balancing Option的优先级不适用
负载平衡Option的格式如下:
IPv4端口Option被SOME/IP-SD实例用于向相关端口发出信号。端口包括本地IP地址、传输层协议(例如UDP或TCP)以及发送方的端口号。这些端口也用于事件和通知事件
IPv4端口选项应使用类型0x04
IPv4端口选项应指定IPv4地址、使用的传输层协议(ISO/OSI第4层)及其端口号
IPv4端口Option的格式如下:
服务器应使用带有Offer Service Entries的IPv4端口Option来向其提供服务的端口发出信号。即最多一个UDP端口和一个TCP端口
服务器使用Offer Service Entry引用的端口也被用来作为事件源。即端口选项中传输协议的源IP地址和源端口号
客户端应使用带有Subscribe Eventgroup Entries的IPv4端口Option来通知IP地址和UDP和/或TCP端口号,在这些端口号上它已准备好接收事件
IPv6端口Option被SOME/IP-SD实例用于向相关端口发出信号。端口包括本地IP地址、传输层协议(例如UDP或TCP)以及发送方的端口号。这些端口也用于事件和通知事件
IPv6端口选项应使用类型0x06
IPv6端口Option的格式如下:
服务器应使用带有Offer Service Entries的IPv6端口选项来向端口发出服务可用的信号。即最多一个UDP端口和一个TCP端口
服务器使用一个Offer Service Entry引用的端口也被用来作为事件源。即端口选项中传输协议的源IP地址和源端口号
客户端应使用带有Subscribe Eventgroup Entries的IPv6端口选项来通知IP地址和UDP和/或TCP端口号,它已准备好接收事件
服务器使用IPv4多播Option来宣布IPv4多播地址、传输层协议(ISO/OSI第4层)以及多播事件和多播通知事件发送到的端口号。作为传输层协议,目前仅支持UDP
IPv4多播选项应由Subscribe Eventgroup Ack Entries引用
IPv4多播选项应使用类型0x14
IPv4多播选项应指定IPv4地址、使用的传输层协议(ISO/OSI第4层)及其端口号
IPv4多播Option的格式如下:
服务器应引用对IPv4多播地址和端口号进行编码的IPv4多播选项。而这个IPv4多播地址和端口号,是服务器发送多播事件和通知事件的地址和端口号
服务器使用IPv6多播Option来宣布IPv6多播地址、第4层协议以及多播事件和多播通知事件发送到的端口号。对于传输层协议(ISO/OSI第4层),目前仅支持UDP
IPv6多播选项应使用类型0x16
IPv6多播选项应指定IPv6地址、使用的传输层协议(ISO/OSI第4层)及其端口号
IPv6多播Option的格式如下:
Subscribe Eventgroup Ack消息应引用IPv6多播选项而不是IPv6端口选项
服务器应引用对IPv6多播地址和端口号进行编码的IPv6多播选项。而这个IPv6多播地址和端口号,是服务器发送多播事件和通知事件的地址和端口号
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的格式如下:
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的格式如下:
Find Service Entry类型用于查找服务实例,并且仅在服务的当前状态未知时才发送(没有接收到当前的Service Offer并且仍然有效)
Find Service Entry应按以下方式设置Entry字段:
发送方不得在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应按以下方式设置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应设置与它们正在停止的Offer Service Entry完全相同的Entry字段,除了:TTL应设置为0x000000
下表显示与允许的Entry类型相关的SOME/IP-SD Option类型:
如果静态配置的值与这些选项中的值不同,则SD应使用在端口和多播选项中传输的IP地址和端口号重写
端口选项的IP地址和端口号也用于传输事件和通知事件
在UDP的情况下,端口选项用于作为事件和通知事件的源地址和源端口,也是客户端能够向其发送方法请求的地址
在TCP的情况下,端口选项用于作为客户端需要打开TCP连接的IP地址和端口,以使用TCP接收事件
SOME/IP应允许服务同时使用UDP和TCP
哪个消息由哪个底层传输协议发送由配置决定:一个Service可以同时使用UDP和TCP端口。但是无论使用TCP还是UDP,每个服务元素都应该配置
需要在配置中限制通过TCP/UDP提供哪些方法和哪些事件。这也意味着不能通过TCP和UDP提供相同的事件
Offer Service Entries引用的端口选项表示:
除了Offer Service Entries的端口选项中给出的端口之外,该服务实例的事件不得从任何其他端口发送
如果一个ECU提供多个服务实例,这些服务实例的SOME/IP消息应通过Offer Service Entries引用的端口选项中传输的信息来区分
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引用的多播选项中指定的端口,以免错过多播事件
下图显示了具有不同端口和多播选项的示例:
请记住,多播端口在接收方使用多播IP地址,而TCP不能用于多播通信
所有SD消息都应发送到SD_PORT
SD_PORT用于SD单播/多播消息的源端口
所有单播SD消息都应将SD_PORT作为目标端口,除非SD端口Option定义了不同的端口
所有SD多播消息都应使用SD_MULTICAST_IP发送
使用之前指定的首部格式,可以构建不同的Entry和由一个或多个Entry组成的消息。具体Entry及其首部布局将在以下部分中进行说明
Subscribe Eventgroup Entry类型用于订阅事件组
Subscribe Eventgroup Entries按以下方式设置Entry字段:
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 Entries应设置与它们正在停止的订阅事件组Entry完全相同的Entry字段,除了:TTL设置为0x000000
Stop Subscribe Eventgroup Entry应引用与Subscribe Eventgroup Entry引用的相同Options。这包括但不限于端口和配置选项
Subscribe Eventgroup Acknowledgment Entry类型用于指示Subscribe Eventgroup Entry已被接受
Subscribe Eventgroup Acknowledgment Entry应按以下方式设置Entry字段:
引用通过多播传输的事件和通知事件的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 Acknowledgment Entry类型应用于指示Subscribe Eventgroup Entry未被接受
Subscribe Eventgroup Negative Acknowledgment Entries应按以下方式设置条目字段:
不接受订阅事件组的原因包括(但不限于):
当客户端在需要TCP连接的SubscribeEventgroup上收到SubscribeEventgroupNack作为应答时,客户端应检查TCP连接并在需要时重新启动TCP连接
服务器可能丢失了TCP连接,而客户端没有
检查TCP连接可能包括以下内容:
如果可以同时发送,SOME/IP Service Discovery通过将Entries打包在一起来减少服务发现消息的数量。例如:
对于每个服务实例,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阶段后,提供者需要等待1*CYCLIC_OFFER_DELAY才能发送第一个offer entry消息
如果配置了CYCLIC_OFFER_DELAY,则在主阶段Offer消息应循环发送
在发送指定的服务实例的消息后,Service Discovery会等待1*CYCLIC_OFFER_DELAY,然后再发送此服务实例的下一条消息
对于Find Entries(Find Service和Find Eventgroup),主阶段中不允许出现循环消息
Subscribe EventGroup Entries应由循环发送的Offer
Entries触发
例如:
初始等待阶段:
重复阶段(REPETITIONS_BASE_DELAY=100ms,REPETITIONS_MAX=2):
主阶段(只要消息处于活动状态并且定义了CYCLIC_OFFER_DELAY):
Service Discovery应使用配置项REQUEST_RESPONSE_DELAY延迟回答在多播SOME/IP-SD消息中接收到的Entries。这适用于以下两种情况:
如果用单播消息回答单播消息,则REQUEST_RESPONSE_DELAY将不适用
REQUEST_RESPONSE_DELAY应由最小值和最大值指定
实际延迟应在REQUEST_RESPONSE_DELAY的最小值和最大值之间随机选择
对于基本实现,所有Find Service Entries都应通过使用单播传输的Offer Service Entries来回答
出于优化目的,应支持以下行为作为选项:
当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
在本节中,显示了客户端和服务器的状态机
SOME/IP Service状态机(服务器)如下图所示:
SOME/IP Service状态机(客户端)如下图所示:
在本节中,讨论了错误情况下的SOME/IP-SD(例如丢失或损坏的数据包)。这也被理解为使用的机制和可能的配置的基本原理
软状态协议:SOME/IP-SD被设计为软状态协议,这意味着Entries具有生命周期,需要刷新才能保持有效(将TTL设置为最大值将关闭此功能)
初始等待阶段:
引入初始等待阶段有两个原因:启动ECU的去偏移事件以避免流量突发,并允许ECU收集SD消息中的多个entries
重复阶段:
引入了重复阶段以允许客户端和服务器的快速同步。如果客户端启动较晚,它会很快找到服务器。而且如果服务器稍后启动,可以很快找到客户端。重复阶段以指数方式增加两条消息之间的时间,以避免过载情况使系统无法同步
主阶段:
在主阶段,SD尝试稳定状态,从而通过不再发送查找服务来降低数据包速率,并且仅在循环间隔(例如每1秒)中提供
请求-响应-延迟:
SOME/IP-SD应配置为通过请求-响应-延迟来延迟对多播消息中entries的回答。这在具有许多ECU的大型系统中很有用。当发送一个包含许多entries的SD消息时,来自不同ECU的大量回复同时到达,并且对接收所有这些回复的ECU施加了很大的压力
上图显示了对传入的SOME/IP-SD消息进行错误处理的简化过程
检查是否存在用于空SOME/IP-SD消息的至少足够字节,即消息至少有12个字节长。如果检查失败,则该消息将被丢弃,无需进一步操作
如果接收到的entry的服务ID未知,则应忽略该entry
如果接收到的entry的实例ID未知,则应忽略该entry
如果接收到的entry的主版本未知,则应忽略该entry
如果接收到的entry的事件组ID未知,则应忽略该条目。这仅适用于事件组entry
如果Entries数组的长度无效(即entries数组将超过消息大小),则应丢弃该消息,无需进一步操作
检查每个收到的Entry引用的选项:
如果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引用的选项将被忽略:
除了SOME/IP之外,车内还使用了其他通信协议;例如,用于网络管理、诊断或闪存更新。此类通信协议可能需要与服务实例通信或还具有事件组
对于非SOME/IP协议(应用程序协议本身不使用SOME/IP,但它通过SOME/IP SD发布)应使用特殊的服务ID,并应使用配置选项添加更多信息:
SOME/IP服务不应使用配置选项中的otherserv-string
对于Find Service/Offer Service/Request Service Entry,在宣布非SOME/IP服务实例时应使用otherserv-String
与SOME/IP请求/响应机制相比,可能存在客户端需要来自服务器的一组参数但不想在每次需要时都请求该信息的情况。这些称为通知和关注事件和字段
所有的客户端需要的事件和/或通知事件都应在运行时使用SOME/IP-SD向服务器注册
通过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没有过期,那么客户端不应请求初始事件
客户明确请求初始事件的原因包括但不限于:
如果客户端订阅了两个或多个事件组,包括一个或多个相同的事件或字段,则服务器不应为该字段发送重复的事件或通知事件。这意味着是常规事件而不是初始事件
客户端链接丢失的发布/订阅描述如下:
将Offer Service Entry作为隐式发布发送的服务器必须保持此事件组实例的订阅事件组消息的状态,以便知道是否必须发送通知/事件
客户端应通过发送TTL=0的SOME/IP-SD订阅事件组消息(停止订阅事件组)从服务器注销
发布/订阅,注册/注销行为描述如下:
下图描述了这个过程
描述是客户端2停止订阅,图里是客户端1停止订阅
如果在发送事件或通知事件后发生相关的SOME/IP错误,服务器上的SOME/IP-SD将删除订阅
错误包括但不限于无法到达通讯伙伴和TCP连接错误
服务器上链接丢失的发布/订阅描述如下:
用图片描述如下:
如果通过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未到达,则客户端应执行以下操作:
这种行为的存在是为了应对短时间的通信丢失,因此会触发新的初始事件以降低消息丢失的影响
如果客户端发送一个订阅事件组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,就应该进行重试
本章概述了保留标识符和特殊标识符
总结了所有使用的配置参数
接收到的SOME/IP-SD消息应检查端口选项和SD端口选项中接收的IP地址是拓扑正确的(参考使用SOME/IP-SD的IP子网中的 IP地址)并且应忽略不是拓扑正确的以及引用这些选项的entries
这意味着只能访问同一子集中的客户端和服务器
在本节中,将讨论服务发现的强制性功能集和相关的配置约束。 这允许在没有当前用例可能不需要的可选的或信息化的功能的情况下进行最低限度的实现
以下信息被定义为合规检查清单。如果未实现某个功能,则认为该实现不符合SOME/IP-SDs基本功能集
应实现以下entry类型:
当需要 IPv4 时,应实现以下option类型:
如果需要IPv6,应实现以下option类型:
以下行为/反应应在服务器端实现:
以下行为/反应应在客户端实施:
客户端应支持以下行为和配置约束:
客户端和服务器应实施本文档中指定的重启检测并做出相应反应。 这包括但不限于:
客户端和服务器应实现“服务和事件的端口处理”。这包括但不限于:
客户端和服务器应实现对初始事件的显式请求
为了支持迁移场景,ECU应支持服务以及使用同一服务的不同不兼容版本
为了支持具有多个版本的服务,需要以下内容:
在一个VLAN中,最多有一个Service ID、Major Version 和Instance ID相同的服务实例。这适用于服务器和客户端网络节点
不允许在一个网络节点上配置多个仅在次要版本上有所不同的服务实例,因为它们在事件组entries中无法区分
词汇表
AUTOSAR_TR_Glossary
SOME/IP协议规范
AUTOSAR_PRS_SOMEIPProtocol