SOMEIP协议理解
SOME/IP协议理解
参考文献:
- AUTOSAR_PRS_SOMEIPProtocol
- AUTOSAR_PRS_SOMEIPServiceDiscoveryProtocol
非官方:
1. SOME/IP
报文:
message ID
唯一标识消息,**method / event **
消息类型为 method
- service ID + method ID
消息类型为 event
- service ID + event ID
length
- 用于识别 SOME/IP消息的结束
request ID
- Client ID + Session ID
- Client ID 唯一标识客户端,client ID 仅 client 需要定义,服务端根据 client ID 区分不同客户端对同一方法的调用
- Session ID ,区分同一发送者的消息顺序,最大值 0xFFFF, 0x01 - 0xFFFF 循环
message type
- 标识消息的类型(5 + 5 种)
- request / request_no_return / notification / response / error
- TP-request / TP-request_no_return / TP-notification / TP-response / TP-error
![someip_header_messagetype_01](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/someip_header_messagetype_01.6dsgwgmvkbk0.webp)
![someip_header_messagetype_02](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/someip_header_messagetype_02.3iefjfz4l0g0.webp)
return type
![someip_procotol_header_returntype](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/someip_procotol_header_returntype.1q44tak2wsm8.webp)
- 标识请求是否成功处理
- 一般为 E_OK
payload
- UDP (0 - 1400 byte)
- TCP (无限制)
直接确定:service ID、method ID、client ID、message type、interface Version == 0x01(由用户定义)
间接确定:return type、length
存在默认值:protocol version == 0x01,
序列化
- 必须内存对齐
- 结构体深度优先搜索
- 基本数据类型
![DeepinScreenshot_select-area_20220125145220](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/DeepinScreenshot_select-area_20220125145220.5fbbwm03utg0.webp)
关于 service instance
- 同一个service的service-instance 通过不同的 instance ID 标识
- 正常来说,不同服务的多个 service-instance 共享传输层协议的同一端口,不过,单ECU上同一服务的多个service-instance使用每个服务实例的不同端口,原因是 instance ID用于服务发现,但他们不包含在 SOME/IP header 中
request/response 通信
- 客户端:
- 构建有效载荷
- 设置message ID 和 request ID
- length = 8 byte ??
- 设置协议版本,接口版本
- message type = 0x00(request)
- return type = 0x00
- 服务端:
- 构建有效负载
- 接管客户端请求中的 request ID
- message type = 0x80 (response) or 0x81(error)
- return type
Notification Events
- SOMEIP负责传输,发布订阅机制由SOMEIP-SD实现
- 服务端:
- 根据服务端发送时间设置 message ID
- message type = 0x02 (notification)
- return type = 0x00 (E_OK)
- 策略
- 以固定时间间隔发送数据
- 一旦某值改变即发送数据
- 当连续发送的某序列值之间差异大于阈值时发送数据
Fields
- getter (读取访问,method)、setter (写访问,method)、notification event (event)
协议选择指南
- 传输数据块 > 1400 byte,并且出错时没有硬延迟要求,使用TCP
- 传输数据块 > 1400 byte,并且出错时有硬延迟要求,使用UDP+SOMEIP-TP
- 数据延迟要求 < 100 ms,使用UDP
2. SOME/IP-SD
描述
- 首要问题:服务实例的状态
- 次要问题:服务的位置(IP地址、传输协议以及端口号)
功能
- 定位服务实例
- 检测服务实例是否运行
- 实现发布/订阅机制
报文
![SOMEIP-SD_header](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/SOMEIP-SD_header.29o8zr2zt5z4.webp)
SOMEIP部分
- message ID = 0xFFFF 0x8100
- client ID = 0x0000
- protocol type = 0x01
- interface type = 0x01
- message type = 0x02 (notification)
- return type = 0x00 (E_OK)
SOMEIP-SD部分
- Flags
- 0-1-2-3-4-5-6-7 ( 8 bit)
- 0,reboot flag:重启标识。重新启动置1,session ID 经过一轮循环后,置0
- 1,unicast flag:单播标识。置1,表明支持使用单播接受消息,因为兼容性才保留
- 2,explicit initial data control flag。显示初始化数据控制标识,置1,表明ECU支持显式初始数据控制
- 3-7,置0
![DeepinScreenshot_select-area_20220126163452](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/DeepinScreenshot_select-area_20220126163452.3y5dy2sxu2w0.webp)
- entries array
- service entry type (16 byte)
- type
- 0x00 = FindService (客户端)
- 0x01 = OfferService (服务端) / StopOfferService (服务端)
客户端主动查找
客户端 —— FindService ——-> 服务端
若服务可用
客户端 <—— OfferService ——- 服务端
服务端服务后续不可用,主动发出StopOfferService报文,通知客户端停止发送请求,取消订阅
客户端 <—— StopOfferService(TTL = 0) ——- 服务端
问:type一致,如何区分OfferService / StopOfferService ?
答:通过 TTL 值进行区分,当TTL = 0 时,表示此时为 StopOfferService,后面的 StopSubscribeEventgroup以及SubscribeEventgroupNack原理一致,注意区分报文中的TTL与TCP/IP协议栈中的TTL,不是一个概念
service ID
- 关于哪个服务,0xFFFF = 所有服务
instance ID
- 关于服务的哪个实例,0xFFFF = 所有实例
major version
- 服务主版本号
TTL
- entries 生命周期,可理解为发现服务时的搜索时间,提供服务时的有效时间
Eventgroup entry type (16 byte)
type
- 0x06 = SubscribeEventgroup (客户端) / StopSubscribeEventgroup (客户端)
- 0x07 = SubscribeEventgroupAck (服务端) / SubscribeEventgroupNack (服务端)
客户端 —— SubscribeEventgroup ——-> 服务端
符合订阅条件,订阅成功
客户端 <—— SubscribeEventgroupAck ——- 服务端
不符合订阅条件,订阅不成功
客户端 <—— SubscribeEventgroupNack (TTL = 0)——- 服务端
客户端取消订阅
客户端 —— StopSubscribeEventgroup(TTL = 0) ——-> 服务端
reserved & reserved2
- 0x00
initial data requested flag
- 初始数据请求标志,若初始数据由服务端发出,则设置为1
counter
- 用于区分同一订阅者的订阅请求
eventgroup ID
- 事件组ID,也就是说SOME/IP事件订阅和取消订阅的颗粒度到一个事件组,而不是一个事件
options部分
- 附加信息,包括如何访问服务实例信息(IP地址、传输协议、端口号)
- 配置选项/负载平衡/endpoint
3. SOME/IP-TP
未完待续
4. 示例
![DeepinScreenshot_select-area_20220127115435](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/DeepinScreenshot_select-area_20220127115435.6iumlrca0000.webp)
5. SOMEIP-SD 状态机
![DeepinScreenshot_select-area_20220127120603](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/DeepinScreenshot_select-area_20220127120603.6at1mnuy39s0.webp)
![DeepinScreenshot_select-area_20220127121252](https://raw.githubusercontent.com/ziyangfu/my-image-hosting/master/DeepinScreenshot_select-area_20220127121252.3rgcie36s2w0.webp)
6. 通过wireshark识别与解析SOME/IP协议
wireshark识别应用层协议采用 端口号-应用层协议绑定(例如:port 80 = HTTP)及自启发识别机制,而SOMEIP协议 wireshark无法通过端口号识别,自启发识别算法失效,因此为了解析SOMEIP协议分组,需手动设置。
- 选择数据包,右键选择
Decode As
- 协议选择SOME/IP协议
- 过滤器键入
someip
或someipsd
可以过滤协议
保持永久设置,实质是绑定端口与协议
点击菜单栏->edit->preference->protocol,选择SOMEIP协议
SOMEIP 及SOMEIP-SD 解析
![image-20230417151307817](/2023/04/17/SOMEIP%E5%8D%8F%E8%AE%AE%E7%90%86%E8%A7%A3/image-20230417151307817.png)