SOME/IP服务发现协议-SD
- 文档说明
- 1. 简介
- 2. 使用场景
- 3. 协议需求和可追溯性
- 4. 缩略语
- 5. 协议说明
-
- 5.1 SOME/IP服务发现(SOME/IP-SD)
-
- 5.1.1 概述
- 5.1.2 SOME/IP-SD消息格式
-
- 5.1.2.1 通用需求
- 5.1.2.2 SOME/IP-SD头(Header)
- 5.1.2.3 Entry格式
- 5.1.2.4 Options格式
-
- 5.1.2.4.1 Configuration Option
- 5.1.2.4.2 负载均衡选项(Load Balancing Option)
- 5.1.2.4.3 IPv4终端选项(IPv4 Endpoint Option)
- 5.1.2.4.4 IPv6终端选项(IPv6 Endpoint Option)
- 5.1.2.4.5 IPv4多播选项(IPv4 Multicast Option)
- 5.1.2.4.6 IPv6多播选项(IPv6 Multicast Option)
- 5.1.2.4.7 IPv4 SD终端选项( IPv4 SD Endpoint Option)
- 5.1.2.4.8 IPv6 SD终端选项(IPv6 SD Endpoint Option)
- 5.1.2.5 服务的Entries(Service Entries)
- 5.1.2.6 服务和事件中的终端处理(Endpoint Handling for Services and Events)
- 5.1.3 服务发现消息(SD Messages)
- 5.1.4 服务发现通信(Service Discovery Communication Behavior)
- 5.1.5 非SOME/IP协议使用SOME/IP-SD
- 5.1.6 使用SOME/IP和SOME/IP-SD协议进行发布/订阅(Publish/Subscribe)
- 5.1.7 SOME/IP和SOME/IP-SD协议的保留和特殊标识符
- 6. 参数配置
- 7. 协议使用
- 8. 参考文档
文档说明
本文档翻译自官方文档:AUTOSAR_FO_PRS_SOMEIPServiceDiscoveryProtocol,需要的请自取;本文档结合了官方文档翻译以及个人总结,如发现有错误的地方,欢迎指正。
1. 简介
本文档描述了协议格式,消息序列以及SOME/IP Service Discovery(SOME/IP-SD)协议的语法规则;
服务发现协议(SOME/IP-SD)的主要作用是控制事件消息的发送以及在车载通信中服务实例(功能实体)的通信可用性,协议只允许在接收者需要的时候发送事件消息(即发布订阅(Publish/Subscribe)模式);该方式也被称为SOME/IP-SD(基于IP协议的可扩展的面向服务的中间件-服务发现)
1.1 协议目的
SOME/IP-SD主要用于:
- 定位服务实例(Service Instance)
- 检测服务实例何时可用
- 实现发布订阅(Publish/Subscribe)处理
1.2 协议适用
SOME/IP-SD被用于在车载以太网中的服务发现;
1.2.1 限制
SOME/IP-SD协议有如下限制:
- SOME/IP-SD协议只支持基于IP协议的通信
- 当通过多播通信方式处理订阅(Subscribe)时。以太网的通信设计需要考虑做以下限制:
- 初始事件应该使用单播传输
1.3 依赖
1.3.1 对其他协议层的依赖
SOME/IP-SD协议依赖于SOME/IP协议,SOME/IP协议支持TCP和UDP协议,但是SOME/IP-SD协议只能使用UDP协议,SOME/IP-SD对其他协议层的依赖见下图:
2. 使用场景
- 服务提供(Service Offering): 服务端在网络中提供服务实例(Service Instance),而不需要在客户端静态配置服务实例的端点;服务提供也包含服务实例的可用性;
- 服务订阅(Service Subscription): 客户端可以发现需要的服务实例并订阅该服务实例的事件组(EventGroup),客户端无需提前获取服务端的端点;
- 灵活的通信方式: 客户端可以在运行时动态地连接服务实例,不需要提前进行静态的配置;
3. 协议需求和可追溯性
无
4. 缩略语
无
5. 协议说明
5.1 SOME/IP服务发现(SOME/IP-SD)
5.1.1 概述
SOME/IP-SD主要用于:
- 定位服务实例(Service Instance)
- 检测服务实例何时可用
- 实现发布订阅(Publish/Subscribe)处理
在车载网络中,服务实例(Service Instance)的地址(IP地址、传输协议、端口)通常是已知的,但服务实例的状态仍然需要重点关注;
5.1.1.1 术语及定义
- 如果服务(Service)需要提供给多个网络接口,则每个网络接口应使用独立的服务器的服务实例;
- 如果服务(Service)需要配置为可以被多个不同的网络接口访问,则每个网络接口应使用独立的服务器的服务实例;
5.1.2 SOME/IP-SD消息格式
5.1.2.1 通用需求
SOME/IP-SD消息应该使用UDP协议发送,且应有如下设置(协议头各字段设置):
- 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消息头格式如下:
- 服务发现协议消息(SOME/IP-SD)的结构应该从一个SOME/IP消息的头开始,且Service-ID应该设置为0xFFFF,Method-ID应设置为0x8100;
- SOME/IP-SD消息的长度字段是在SOME/IP头中,长度字段的值是从长度字段之后的字段(通常是Request ID)开始,一直计算到SOME/IP-SD整个包的结束位置,单位为字节;
- SOME/IP-SD的Client-ID字段应设置为0x0000,因为只存在一个SOME/IP-SD实例;
- 每发送一个SOME/IP-SD消息,SOME/IP-SD消息中SOME/IP头里面的Session ID的值都应该增加1;
- SOME/IP-SD消息的Session ID的初始值应该设置为1(不能被设置为0),当自增溢出后也应该重置为1;
- 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-SD消息中的所有字段都应该使用大端模式(Big Endian Byte Order);
以下为一个实际的SOME/IP-SD消息的示例:
5.1.2.2 SOME/IP-SD头(Header)
SOME/IP-SD消息应该通过SOME/IP进行发送;
SOME/IP-SD消息的头(在Tbale 5.1中除开SOME/IP头剩余的部分)应该从一个8 BIT的Flags字段开始,该字段的结构见下图:
- SOME/IP-SD的Flags字段的第1个BIT位是 Reboot Flag;当重启之后,所有SOME/IP-SD消息的 Reboot Flag 字段都要设置为 1 ,直到SOME/IP-SD消息中的Session ID字段的值自增并溢出后,重新回到1时,Reboot Flag字段被重置为0;
- 对于多播和单播,SOME/IP-SD消息的 Reboot Flag 和 Session ID 的值应该被分开存储,且对每一对已建立连接的“发送者-接收者”都应该独立存储值;
- 对发送方和接受方都应该分别存储自己的计数器:
- 发送方:
- 有一个多播的计数器
- 每个单播都应该有一个单独的计数器
- 接收方:
- 每个多播都应该有一个单独的计数器
- 每个单播都应该有一个单独的计数器
- 发送方:
- 重启(Reboot)的检测逻辑如下(通过当前收到的包与上一个收到的旧包的字段值进行比对):
- 如果
old.reboot == 0 and new.reboot == 1
则表示检测到重启 - 或者如果
old.reboot == 1 and new.reboot == 1 and old.session_id >= new.session_id
则表示检测到重启
- 如果
- SOME/IP-SD的Flags字段的第2个BIT位是 Unicast Flag;所有SOME/IP-SD消息的Unicast Flag字段应设置为1,这表示接受方支持使用单播;
- 发送SOME/IP-SD消息时,Flags字段的剩余BIT位都应设置为0,且接收方需要忽略这些字段;
SOME/IP-SD头的Flags字段之后是一个保留字段(Reserved),该字段是一个24 BIT的字段;
SOME/IP-SD头只有以上两个字段,然后是SOME/IP-SD消息的内容,第一个是:Entries Array;接收方在收到SOME/IP-SD消息时,应该按照Entries Array接收的顺序进行处理;
然后是一个 Option Array 字段,Entries Array 字段和 Options Array 字段都应该从一个 UINT32 类型的长度字段开始,该长度字段的值是 Entries Array 字段和 Options Array 字段的长度(按字节计算);
5.1.2.3 Entry格式
SOME/IP-SD消息中应该支持同时存在多个Entries,Entries是用于同步服务实例的状态和发布/订阅流程;在SOME/IP-SD包中通常是一个Entries列表(数组),其中存储了多个Entry信息;
共有2种类型的Entries:用于服务(Service)的 Service Entry 和用于事件组(EventGroup)的 EventGroup Entry;
第一种、每个Service Entry占用16个字节,且有如下字段(按照先后顺序排列):
- Type Field [uint8]:FindService(0x00),OfferService(0x01),StopOfferService(0x01)
- Index First Option Run [uint8]:在Option Array 列表中,第一个引用的起始序号(Index)
- Index Second Option Run [uint8]:在Option Array 列表中, 第二个引用的起始序号(Index)
- Number of Options 1 [uint4]:在Option Array 列表中, 第一个引用的个数
- Number of Options 2 [uint4]:在Option Array 列表中, 第二个引用的个数
- Service ID [uint16]:服务ID或Entry相关的服务实例
- Instance ID [uint16]:服务实例ID,或当一个服务的所有实例都是必须的情况下,该值应该被设置为0xFFFF;
- Major Version [uint8]:服务的主版本信息
- TTL [uint24]:Entry的生命周期,单位为秒(s)
- Minor Version [uint32]:服务的次版本信息
第二种、每个EventGroup Entry占用16个字节,且有如下字段(按先后顺序排列):
- Type Field [uint8]:Subscribe (0x06), StopSubscribeEventgroup (0x06), SubscribeAck (0x07) and SubscribeEventgroupNack (0x07)
- Index First Option Run [uint8]:在Option Array 列表中,第一个引用的起始序号(Index)
- Index Second Option Run [uint8]:在Option Array 列表中, 第二个引用的起始序号(Index)
- Number of Options 1 [uint4]:在Option Array 列表中, 第一个引用的个数
- Number of Options 2 [uint4]:在Option Array 列表中, 第二个引用的个数
- Service ID [uint16]:服务ID或Entry相关的服务实例
- Instance ID [uint16]:服务实例ID,或当一个服务的所有实例都是必须的情况下,该值应该被设置为0xFFFF;
- Major Version [uint8]:服务实例的主版本信息
- TTL [uint24]:Entry的生命周期,单位为秒(s)
- Reserved [uint12]:保留位,应设置为0x000
- Counter [uint4]:用于区分来自同一个订阅者订阅的不同事件组,如果不使用则设置为0x0
- Eventgroup ID [uint16]:用于传输ID和事件组(EventGroup)
Entry的主版本信息(Major Version)应该与对应的服务接口(Service Interface)的版本相匹配;
由于SOME/IP-SD已经定义了接口的主要版本(Major Version)和次要版本(Minor Version)信息,SOME/IP消息中则只需要使用SOME/IP头中接口版本(Interface Version)字段定义的版本信息;
5.1.2.3.1 从Entries中引用Options
Entries中使用了如下字段后,则可以引用Options中的项:
- Index First Option Run:在Option Array列表中,第一个引用的起始序号,0表示引用Option Array中的第一个值
- Index Second Option Run:在Option Array列表中,第二个引用的起始序号,0表示引用Option Array中的第一个值
- Number of Options 1:第一个引用的数量,0表示不需要引用,1表示仅引用从Index First Option Run开始的第1个项,2表示引用从Index First Option Run开始的2个项
- Number of Options 2:第二个应用的数量,0表示不需要引用,1表示仅引用从Index Second Option Run开始的第1个项,2表示引用从Index Second Option Run开始的2个项
一个SOME/IP-SD包中的Entries中通常可能存在多条数据,此时Entry Array中每个Entry需要引用的Option Array中的位置不同,甚至有可能是间隔开的,因此支持两个Option Run参数时最高效的方式,同时可以保证线格式的高效;
在SOME/IP-SD包中,有两个数组:Entry Array 和Option Array,其中Entry Array中每一个Entry都需要指定自己能支持的协议或端口号等信息,但由于每个Entry支持的协议和端口号可能相同也可能不同,因此将这些协议和端口号信息统一按照列表的形式放在另一个数组Option Array中,然后再Entry中通过配置Option Array列表中的序号以及数量来决定当前的Entry使用的是哪一个Option或者哪几个Options(在这种情况下,通常只需要使用一组参数就够了: Index First Option Run 和 Number of Options 1);但是有时候可能一个Entry中需要指定Option Array中的多个项,而且这些选项可能是不连续的,因此就会用到第二组参数;建议使用一个实际的包进行辅助理解;
如果 Number of Options x 被设置为0,则表示该参数没有相关的Option被配置,且对应的Index x Option Run参数也应该被设置为0;如果Number of Options x 被设置为0且Index x Option Run参数没有设置为0,则接收到该SOME/IP-SD包后需要忽略该包;
5.1.2.4 Options格式
Options是用于为Entry传输额外的信息,主要包括:IP地址、传输协议(Protocol)、端口号(Port),Options通常在SOME/IP-SD协议中是一个列表(数组)的形式,存储多个Option信息;
每个Option都有如下字段:
- Length [uint16]:Option的字节数,即长度
- Type [uint8]:Option的类型
- Discardable Flag [1 bit]:该Option是否可以被丢弃
- Bit 1 to bit 7:保留位,应被设置为0
Discardable Flag 被设置为1时,表示当接收方的ECU不支持该Option时,可以丢弃该Option;
5.1.2.4.1 Configuration Option
Configuration Option 可以用于传输任意的配置字符串,这允许对如服务名称或配置等额外信息进行编码;另外,Option配置还可以通过SOME/IP-SD协议提供非SOME/IP的服务;
Configuration Option格式如下:
- Length [uint16]:Configuration Option占用的总字节数,不包括16 BIT的长度字段(即本字段)和8 BIT的类型字段(Type);
- Type [uint8]:应设置为0x01
- Discardable Flag [1 bit]:该Option是否可以被丢弃,1表示可以被丢弃
- Bit 1 to bit 7:保留位,设置为0
- ConfigurationString [dynamic length]:动态长度,包含Configuration Option的字符串
Configuration Option应该基于DNS TEXT和DNS-SD格式指定一系列对应的键值对;
Configuration字符串的格式应该从一个字节(8 BIT)的长度字段(Length)开始,该长度字段表示在后面的所有字节数(不包含长度字段本身),然后是一个与长度字段中指定的长度对应的字符串,在该字符串后面,紧接着是第二个长度字段和第二个字符串(第三个长度字段和第三个字符串,以此类推);直到某个长度字段的值被设置为0x00(被设置为0x00的长度字段后面不能跟随任何字符串),则表示结束;
在每个长度字段后面的字符串都应该包含一个编码后的键值对(其中值是可选的,可以只有键,没有值),键值对使用 = 进行连接,即 key=value,键(Key)里面不能再包含等号“=”且要至少有一个非空白的字符,且键(Key)的字符串需要是可以打印的 US-ASCII 的值(0x20 - 0x7E),不包含等号“=”(0x3D);
等号“=”不能是字符串的第一个字符;
对于一个不包含“=”的字符,键(Key)应被认为是存在的;
对于一个以“=”作为结束字符的字符串,应该认为键(Key)是存在的,但是值(Value)为空;
应该支持多个Entries使用同一个Configuration Option中的同一个键(Key)的情况;
Configuration Option格式:
SOME/IP-SD Configuration Option示例:
5.1.2.4.2 负载均衡选项(Load Balancing Option)
负载均衡(Load Balancing Option)是用于按照优先级顺序处理同一个服务(Service)下的不同实例(Instance),以便客户端可以动态地选择需要使用的服务实例;且该Option需要通过Offer Service中的Entries提供;
负载均衡(Load Balancing Option)需要携带一个优先级(Priority)和一个权重(Weight)信息(类似于DNS-SRV记录),这两个信息会用于均衡不同的服务实例;当查找服务的所有实例(Service Instance设置为xFFFF)时,客户端可以选择满足客户端标准且优先级最高的服务实例(客户端的标准通常可以被客户端的应用层定义,用于在服务端提供的服务实例中进行选择使用合适的实例;客户端标准不会在需求中定义且可以限制使用服务实例的ID范围);
当同时有多个最高优先级(Priority)的服务实例存在时,客户端对服务实例的选择是根据权重(Weight)的值来进行随机选择的;选择一个服务实例的概率是该服务实例的权重(Weight)除以所有服务实例的权重之和的值;
如果提供的多个服务实例均没有配置负载均衡选项(Load Balancing Option),则客户端应认为这些提供的服务实例的优先级均为最低优先级;
当仅查找特定的服务实例时(Service Instance设置为除xFFFF之外的任意值),不需要应用负载均衡(Load Balancing Option)评估机制;
负载均衡选项(Load Balancing Option)的格式如下:
- Length [uint16]:应设置为0x0005
- Type [uint8]:应设置为0x02
- Discardable Flag [1 bit]:如果需要允许接收方可以丢弃该Option的话则设置为1,否则设置为0
- Bit 1 to bit 7:保留位,设置为0
- Priority [uint16]:实例的优先级,值越小表示优先级越高
- Weight [uint16]:实例的权重,值越大表示被选中的可能性越大
5.1.2.4.3 IPv4终端选项(IPv4 Endpoint Option)
EndPoint通常表示网络中的一个点或者说是目标地址,它可以是一台电脑、一部手机或者是服务器上运行的一个应用;EndPoint组件通常包含两个主要部分:IP地址和端口号。IP地址是网络中节点的唯一标识,而端口号则用于区分不同的网络服务或应用。通过IP地址和端口号的组合,我们可以准确地定位到网络上的任何一个EndPoint;
IPv4 Endpoint Option 用于SOME/IP-SD的实例,用于表示相关的终端(Endpoint);终端(Endpoint)包含IP地址和传输层协议(UDP/TCP)和发送方的端口号,这些端口号同时也用于事件(Events)和通知(Notifications);
IPv4 Endpoint Option 应该使用的Type是0x04;
IPv4 Endpoint Option 应指定IPv4的地址、传输层协议(ISO/OSI第4层)和端口号;
IPv4 Endpoint Option的格式如下:
- Length [uint16]:应设置为0x0009
- Type [uint8]:应设置为0x04
- Discardable Flag [1 bit]:应设置为0
- Bit 1 to bit 7:保留位,设置为0
- IPv4-Address [uint32]:用4个字节指定单播的IP地址
- Reserved [uint8]:应设置为0x00
- Transport Protocol (L4-Proto) [uint8]:基于IANA/IETF类型(0x06: TCP, 0x11: UDP)指定传输层(ISO/OSI layer 4)的协议;
- Transport Protocol Port Number (L4-Port) [uint16]:第4层协议使用的端口号;
服务端应在提供的服务Entries中使用IPv4 Endpoint Option,用于向服务实例告知所在的Endpoint,这取决于使用的UDP终端还是TCP终端;
提供的服务中的Entries中的服务相关的终端(Endpoint)也可以用于事件(Events)来源,即