【Eclipse OpenSOVD学习之二】 SOVD 协议原理与标准背景

01. SOVD 协议原理与标准背景

1. 背景与原理

1.1 标准族:ISO 17978 系列(2026 年发布)

部分 正式标题 状态
ISO 17978-1:2026 Road vehicles --- Service-oriented vehicle diagnostics (SOVD) --- Part 1: General information, definitions, rules and basic principles 2026-05 发布,第 1 版,13 页,ISO/TC 22/SC 31
ISO 17978-2:2026 Part 2: Use cases definition 2026 年发布
ISO 17978-3:2026 Part 3: Application programming interface (API) 2026-03 发布(本项目直接实现对象)

Part 1 的官方范围摘要(ISO 官网):

This document: gives an overview of the ISO 17978 series; specifies rules and basic principles for the service-oriented vehicle diagnostics (SOVD), conforming to the extended vehicle (ExVe) methodology, as specified in the ISO 20077 series; defines general terms.

三个关键点:

  1. 遵循扩展车辆(ExVe)方法学 ISO 20077 ------ SOVD 不是孤立的诊断协议,而是"扩展车辆"体系的一部分。ExVe 解决的是「车辆数据如何在车端、云端、第三方之间受控流转」的治理问题,SOVD 是其在诊断域的 API 落点。
  2. 2026 年才发布第 1 版 ------ 这是非常新的标准,本项目是与标准同步演进的早期实现(也解释了功能完成度低)。
  3. Part 3 的范围 (标准摘要):定义 SOVD API,用于标准化 HPC(高性能计算单元)与传统 ECU 的诊断方法、检索诊断能力、发现扩展车辆中的 SOVD 服务;API 功能包含故障访问(读取故障条目、读取环境数据)等。

1.2 为什么需要 SOVD:从 UDS 到面向服务

维度 经典 UDS(ISO 14229) SOVD(ISO 17978-3)
交互模型 请求/响应式服务原语(0x22 读数据、0x2E 写数据、0x19 读 DTC、0x31 例程、0x34~0x37 刷写) HTTP REST 资源 + JSON
寻址 物理/功能寻址 + ECU 地址 + 专有传输(CAN/ISO-TP、DoIP) URL 路径 /sovd/v1/components/{id}/data/{data_id}
拓扑 静态描述(ODX/PDX 数据库离线加载) 运行时可发现:实体集合 + 能力自描述 + 发现机制
软件实体 只有 ECU 一等公民 App(Component 上运行的软件),适配 HPC 上"一硬件多软件"
工具链 专用诊断仪 + ODX 运行时 任意 HTTP 客户端、curl、浏览器、LLM(MCP)
消费者 售后诊断仪 车端、云端、远程诊断、CI、AI Agent

驱动因素(基于 Part 3 范围与项目生态):中央计算/HPC 架构使得"ECU 数量"与"软件实体"解耦;软件定义汽车需要远程、批量、自动化的诊断能力;云原生工具链(HTTP/JSON/OpenAPI)可直接使用,不再依赖车载专有的 ODX 栈。

1.3 资源模型:Areas / Components / Apps / Functions

层级(来自 opensovd-cli/mcp/src/main.rs 的 server instructions):

复制代码
Areas > Components > Apps > Functions
实体 含义 关系字段
Area 整车架构的逻辑视图(域 / 区,如 powertrain、network) ------
Component 硬件单元(ECU / HPC 板) area_id(belongs-to)
App 运行在 Component 上的软件 is_located_on(宿主 Component,恰 1 个)、area_id(可选)
Function 跨实体的功能视图(根级集合) 本仓库仅有 href 字段,未实现

关系语义:

  • is-located-on:App → 其宿主 Component(apps/{id}/is-located-on),恰好 1 个
  • hosts:Component → 其上运行的 Apps(components/{id}/hosts
  • belongs-to:Component/App → 所属 Area,0 或 1 个
  • contains:Area → 其包含的 Components Apps
  • subcomponents / subareas / depends-on:字段存在,未实现

1.4 能力集合(capabilities)

EntityCapabilities 是 SOVD 的"能力广告牌"------客户端通过它知道"这个实体能干什么、下一步去哪"。完整字段(opensovd-models/src/discovery.rs:52-157,注释中按 C1~C5 条件分组):

分组 能力 含义 / 经典对应
C1 资源集合 data 数据资源读写(UDS 0x22/0x2E)
data-lists 预定义数据项列表,一次读多项以减少往返
faults 故障内存 / DTC(UDS 0x19)
operations 可执行操作 / 例程(UDS 0x31)
configurations 变体配置 / 编码
bulk-data 大块数据传输(刷写、日志下载,UDS 0x34~0x37)
updates 软件更新
modes ECU 模式 / 会话(UDS 0x10/0x11/0x28)
C2 引用集合 locks 资源互斥锁(多客户端并发)
logscommunication-logs 事件日志、诊断通信审计
cyclic-subscriptions 周期性订阅/推送,替代轮询采样
scriptstriggers 服务端脚本、事件触发
belongs-tocontainshostsis-located-ondepends-on 关系引用
C3 variant 变体标识
C4 根级集合 areascomponentsappsfunctions 仅根实体出现
C5 子集合 subcomponentssubareas 层级嵌套

data 的四类分类opensovd-models/src/data.rs):

  • identData ------ 固定标识参数(零件号、VIN、软件版本),只读
  • currentData ------ 动态测量值(电压、温度),只读
  • storedData ------ 参数,可读可写
  • sysInfo ------ 动态系统资源(CPU 负载),只读
  • x-<ext>-* ------ 自定义扩展前缀

1.5 API 约定

版本化与发现

复制代码
GET /sovd/version-info        ← 故意不在 /v1 下:版本发现必须先于版本化访问
GET /sovd/v1/...              ← 版本化业务资源

version-info 响应:

json 复制代码
{ "sovd_info": [ { "version": "1.1",
                   "base_uri": "http://127.0.0.1:7690/sovd/v1",
                   "vendor_info": { "version": "0.1.1", "name": "OpenSOVD" } } ] }

客户端侧对应标准"版本协商"模式:Discovery(版本无关)→ 读 version-infoselect(|s| s.version == "1.1") → 得到绑定该版本的 Client

HATEOAS :每个 capabilities 响应是一张"下一步可去哪"的链接表,href 为绝对 URI,客户端无需拼装路径、可纯靠链接遍历。

include-schema :几乎所有 GET 支持 ?include-schema=true,响应在 schema 字段内联返回 JSON Schema(由 schemars 生成),便于客户端自动生成类型与校验。

错误模型 GenericErroropensovd-models/src/error.rs):

jsonc 复制代码
{ "error_code": "...",      // 必填,kebab-case
  "vendor_code": "...",     // 可选
  "message": "...",         // 必填
  "translation_id": "...",  // 可选
  "parameters": { } }       // 可选

ErrorCode 全部 15 个取值:error-responseincomplete-requestinsufficient-access-rightsinvalid-response-contentinvalid-signaturelock-brokennot-respondingprecondition-not-fulfilledsovd-server-failuresovd-server-misconfiguredupdate-automated-not-supportedupdate-execution-in-progressupdate-preparation-in-progressupdate-process-in-progressvendor-specific

注意 lock-broken 与 4 个 update-* 码的存在:标准明确设计了并发锁软件更新场景,而本仓库两者均未实现。

1.6 架构角色:server / gateway / client

  • SOVD server :持有一份实体集合,对外提供 /sovd/v1。可以是 ECU 内嵌、车内 HPC、或云端。
  • SOVD client:消费 API,支持版本协商。
  • SOVD gateway聚合层 ------把多个下游 SOVD server 的实体汇聚成统一视图。本项目的聚合机制是 DiscoveryProvider(见 04)。

1.7 与 UDS / DoIP / OBD 的关系

  • 本仓库不含任何 UDS/DoIP/OBD 协议栈代码OBD 仅作为数据项的一个 tag 出现。即 opensovd-core 是纯 HTTP/JSON 层。
  • 生态仓库揭示连接方式 (同组织):uds2sovd-proxy(UDS↔SOVD 协议转换代理)、classic-diagnostic-adapter(经典诊断适配器)、odx-converter(ODX→SOVD 描述转换)、fault-libdlt-tracing-lib(对应 logs 能力)。

SOVD 不复用 UDS 服务原语,而是拥有独立资源模型;遗留 UDS ECU 需经由代理/适配器接入 SOVD 世界。对应关系:

SOVD 能力 经典对应
data(ident/current/stored/sysInfo) UDS 0x22 / 0x2E
faults UDS 0x19 + SAE J2012 DTC 格式
operations UDS 0x31
modes UDS 0x10 / 0x11 / 0x28
bulk-data UDS 0x34~0x37
locks UDS 无直接对应(SOVD 新引入,多客户端并发所需)

2. 当前实现架构:协议要素 → 代码落点

协议要素 代码落点 状态
版本发现 /version-info opensovd-server/src/routes/version.rs
实体集合 /components /apps /areas opensovd-server/src/routes/entities/*
能力自描述 EntityCapabilities opensovd-models/src/discovery.rs(22 字段全定义) ⚠️ 仅填 4 组
关系路由 hosts/belongs-to/is-located-on/contains routes/entities/{component,app,area}.rs
data 读写 + categories/groups routes/data.rs + opensovd-core/src/data.rs
错误模型 GenericError + 15 个 error_code opensovd-models/src/error.rsroutes/error.rs ⚠️ 仅用 5 个
include-schema opensovd-server/src/schema.rs
发现/聚合 DiscoveryProvider opensovd-core/src/discovery.rsserver.rs::run_discovery ⚠️ 仅 trait + 测试 mock
faults / operations / configurations / bulk-data / modes / locks / logs / updates / subscriptions ------ ❌ 全部未实现
单位模型 opensovd-extra/src/unit.rs ⚠️ 有模型无换算函数

一句话:协议骨架(版本、实体、关系、数据、错误、schema)已落地,协议肌肉(故障、例程、配置、刷写、模式、锁、日志、订阅)尚未生长。

3. 核心流程与算法:一次标准 SOVD 访问

3.1 版本协商流程(客户端视角)

复制代码
Client::builder().base_uri("http://host/sovd")
  └─> Discovery::versions::<VendorInfo>()
        ├─ GET {base}/version-info            (OnceCell 缓存,同会话只取一次)
        ├─ 解析 Vec<SovdInfo<V>>
        └─ select(|s| s.version == "1.1")
              └─ 取 base_uri(已含 /v1)→ 构造绑定版本的 Client

关键点:base_uri 由服务端下发而非客户端拼装,这是 SOVD 支持多版本并存与网关级联的基础。

3.2 能力发现流程(HATEOAS 遍历)

复制代码
GET /sovd/v1/                        → 根能力(areas/components/apps 三个 href,仅当非空时给出)
GET /sovd/v1/components              → Vec<EntityReference>{id, name, href, tags}
GET /sovd/v1/components/{id}         → EntityCapabilities{id, name, variant, hosts, belongs_to, data, ...}
GET /sovd/v1/components/{id}/hosts   → 其上的 Apps
GET /sovd/v1/components/{id}/data    → 数据项列表(可按 groups/categories/tags 过滤)
GET /sovd/v1/components/{id}/data/{data_id}  → 读值(?include-schema=true 附带 schema)
PUT /sovd/v1/components/{id}/data/{data_id}  → 写值(204 / 400 / 404)

客户端可完全靠 href 逐层下钻,无需知道 URL 模板------这就是 HATEOAS 在 SOVD 中的价值(E2E 测试正是这样遍历全 API)。

3.3 网关聚合流程(标准意义的 gateway)

复制代码
[下游 SOVD server A] ─┐
[下游 SOVD server B] ─┼─> DiscoveryProvider::discover() → Stream<(remove, add)>
[mDNS/SD 发现源   C] ─┘                                        │
                                                               ▼
                                       select_all 合并 → 单条写守卫内应用差分
                                       (remove 先于 add,components→apps→areas)
                                                               │
                                                               ▼
                                              共享 Topology ──> /sovd/v1 对外暴露统一视图

这是 SOVD "聚合"角色的核心算法,详见 04 章 §3.4

4. 待完善与风险

4.1 协议符合性缺口(严重)

  1. 能力广告不完整EntityCapabilities 22 个字段中仅填充 id/name/translation_id/variant/hosts/belongs_to/is_located_on/contains/data/areas/components/apps,其余恒为 None。对客户端而言,未实现的能力与"该实体不支持"不可区分------标准语义上应该用"字段缺省"表达"不支持",这一点是符合的,但客户端无法区分"不支持"与"未实现"
  2. functions 实体缺失 :根级四集合中 functions 从未填充,App 之下的 Function 层级完全没有建模。
  3. 无订阅/推送机制cyclic-subscriptions 未被实现,也没有 WebSocket/SSE 通道,客户端只能轮询------对于实时数据(currentData)场景是重大缺口。
  4. 锁与并发控制缺失locks 能力与 lock-broken 错误码均未使用,多客户端并发写无保护。
  5. 软件更新能力缺失 :4 个 update-* 错误码定义了却无对应流程。

4.2 错误处理语义偏差(中)

  1. vendor-specific 被滥用 :实体不存在返回 vendor-specific + vendor_code: entity-not-found,而标准语义上 vendor-specific 应留给厂商扩展;更贴切的是 error-response 或专门的码。
  2. 写只读资源返回 400 error-response :语义上 405 Method Not Allowed 或 precondition-not-fulfilled 更准确。
  3. 内部错误一律 500 + 脱敏 :符合安全实践,但缺少 sovd-server-failure / sovd-server-misconfigured 的区分使用。
  4. invalid-signature 定义了却不校验WriteRequest.signature 字段被解析后完全忽略,签名/完整性校验链路缺位(安全与合规风险)。

4.3 标准演进跟踪(建议)

  1. ISO 17978 三部分均于 2026 年发布第 1 版,标准仍在快速演进(Part 1 的生命周期显示 2023-04 立项 → 2026-05 发布)。建议:
    • 建立标准条款 → 代码落点的可追溯矩阵(本文件 §2 的表格可作为起点)
    • 关注 ExVe(ISO 20077)方法学对数据治理的影响:SOVD 不只是 API,还涉及授权、审计、数据分级
    • 生态侧关注 classic-diagnostic-adapter 的成熟节奏------它决定了 SOVD 接入存量 UDS ECU 的可行性

5. 关键代码位置

内容 路径
能力模型(22 字段) opensovd-models/src/discovery.rs:52-157
错误码(15 个)与 GenericError opensovd-models/src/error.rs:10-78
data 分类(ident/current/stored/sysInfo) opensovd-models/src/data.rs:10-25
版本信息与 vendor info opensovd-models/src/version.rs
实体层级说明(MCP instructions) opensovd-cli/mcp/src/main.rs:123-131
标准链接 opensovd-core/README.md:17
相关推荐
程序员良辰1 小时前
Eclipse Memory Analyzer(MAT)入门教程:从生成 Heap Dump 到定位 Java 内存问题
java·ide·eclipse·tomcat·idea
蓝天下的守望者1 小时前
ARM SOC architecture学习文档整理
arm开发·学习
pjj198541 小时前
Hadoop-python中使用大数据1
java·ide·eclipse
叶子野格2 小时前
《Verilog学习:前置知识》
学习·fpga开发
wuyk5552 小时前
从零吃透 MQTT 通信|第 6 章 MQTT 主题、过滤器、通配符、订阅管理、拒收机制详解与代码实现
c语言·stm32·学习
sunshine22 girl12 小时前
Java学习一 环境配置2 安装和基本使用Idea
java·学习·intellij-idea
Kobebryant-Manba13 小时前
学习Bert微调
人工智能·学习·bert
xian_wwq13 小时前
【学习笔记】深度认知系列-第14讲 端侧AI崛起——为什么AI正在从云端走向本地
人工智能·笔记·学习
我爱cope14 小时前
【计算机网络 | 传输层3:TCP 协议概述:面向连接、可靠传输到底意味着什么?】
网络·网络协议·学习·tcp/ip·计算机网络·传输层