本文档聚焦于 jidu_vehicleInfo.cpp 与 jidu.cpp 中围绕车辆全生命周期状态的一组查询 API:车辆激活状态、当前运行环境、环境切换工单审批流转、以及贯穿 OTA 升级路径的版本信息查询链路。这些 API 面向售后诊断场景(diag 主机),由 OTX 诊断序列通过 jidu.h 中声明的 C 风格导出函数调用,底层统一走 JiduClient::callServer() 路由到集度云端微服务。
整体架构:请求路由与缓存模式
系统中所有远程查询均通过 callServer(iType, ...) 调用,iType 作为请求类型标识映射到 jidu_uri.h 中的 vtable[] 路由表。对于售后(diag 主机)的请求,调用链路为:上层 API → callServer → JiduClient::callServer → HTTP POST(带 ECDSA 签名)→ callServer_affterHandler 解析并缓存响应。查询结果存入 DataCenter::m_callServerRecord 中,后续的"取缓存"版本 API(如 get_jd_orderInfo_vehicleActiveStatus())直接从缓存中解析 JSON,不再发起网络请求。
Sources: jidu_client.cpp
flowchart TB
subgraph OTX诊断序列
A1["get_jd_vehicleActiveStatus(vin)"]
A2["get_jd_vehicleEnvStatus()"]
A3["get_jd_vehicleEnvChangeWorkFlowStatus(...)"]
A4["get_jd_vehicleSoftApps(...)"]
A5["get_jd_vehicleSoftUpgradePath(...)"]
end
subgraph API层 [jidu_vehicleInfo.cpp / jidu.cpp]
B1["构造 JSON 请求体"]
B2["callServer(iType, ...)"]
B3["从 m_callServerRecord 缓存解析"]
end
subgraph JiduClient [jidu_client.cpp]
C1["callServer_preHandler: 清缓存"]
C2["ECDSA 签名 + diagHost 路由"]
C3["HTTP POST → parsed()"]
C4["callServer_affterHandler: 解析并存储"]
end
subgraph 云端
D1["/uds/vehicle/info/queryByVin (82)"]
D2["/uds/vehicle/env/getVehicleEnvByVin (85)"]
D3["/uds/vehicle/vehicleEnvChangeWorkFlow/queryStatus (87)"]
D4["/uds/vsp/queryVehicleSoftApps (88)"]
D5["/uds/vsp/getVehicleSoftUpgradePath (90)"]
end
A1 --> B1 --> B2 --> C1 --> C2 --> D1
C2 --> D2
C2 --> D3
C2 --> D4
C2 --> D5
D1 & D2 & D3 & D4 & D5 --> C3 --> C4 --> B3Sources: jidu_uri.h, jidu_client.cpp
一、车辆激活状态(Vehicle Active Status)
激活状态标识车辆在集度云端的生命周期阶段,决定后续诊断与刷写操作的可用性。
1.1 远程查询:get_jd_vehicleActiveStatus
该函数以 VIN 为唯一参数构造 JSON 请求体,调用 callServer(82, ...) 请求类型 82 对应的接口 /uds/vehicle/info/queryByVin(POST),从响应的 data.vehicleInfo.vehicleActiveStatus 字段提取整型激活状态。
| 返回值 | 含义 |
|---|---|
1 | 未激活 |
2 | 已激活 |
3 | 工程模式 |
-1 | 查询失败或解析异常 |
构造请求时仅携带 vin 字段,不依赖 deviceSn 之外的任何上下文。函数内部自行管理 JSON 内存(cJSON_CreateObject / cJSON_Delete),对调用方透明。
Sources: jidu_vehicleInfo.cpp
1.2 缓存读取:get_jd_orderInfo_vehicleActiveStatus
该函数不发起网络请求,直接从 DataCenter::m_callServerRecord[82].response 中读取上一次 callServer(82) 的原始响应 JSON 并解析。其解析逻辑比远程版本更健壮——同时兼容两种响应结构:
- 嵌套结构:
data.vehicleInfo.vehicleActiveStatus - 扁平结构:
data.vehicleActiveStatus
如果缓存中不存在记录 82(即从未调用过激活状态查询),返回 -1。
Sources: jidu_vehicleInfo.cpp
1.3 典型调用流程
在 OTX 诊断序列中,典型使用模式是:先调用 callServer(82, ...) 触发查询,再调用 get_jd_orderInfo_vehicleActiveStatus() 从缓存取结果。callServer(82) 的 affterHandler 仅做 response 存储(无特殊解析),激活状态的解析完全由上述两个函数完成。
Sources: jidu_client.cpp
二、车辆环境状态(Vehicle Environment Status)
车辆环境状态描述车辆当前所在的云端服务环境——Prod(生产)、Staging(预发布)以及特殊状态(如证书注销、诊断仪数据清除)。这与本地诊断仪通过 EnvConfig 检测的环境(见 EnvConfig:多环境配置切换机制)是两个独立维度。
2.1 远程查询:get_jd_vehicleEnvStatus
调用 callServer(85) → 接口 /uds/vehicle/env/getVehicleEnvByVin(POST),解析 data.vehicleEnvStatus 字段返回整型环境码。
2.2 状态名称映射:get_jd_vehicleEnvStatusName
该函数以 get_jd_vehicleEnvStatus() 为基础,将数值映射为人类可读字符串:
| 状态码 | 字符串名称 | 含义 |
|---|---|---|
1 | prod | 生产环境 |
2 | staging | 预发布环境 |
3 | prod pki证书注销 | 生产环境 + PKI 证书已注销 |
4 | staging pki证书注销 | 预发布 + PKI 证书已注销 |
5 | prod 诊断仪数据清除 | 生产环境 + 诊断仪数据已清除 |
6 | staging 诊断仪数据清除 | 预发布 + 诊断仪数据已清除 |
| 其他 | 未知 | 未识别状态 |
Sources: jidu.cpp
2.3 与订单信息中的车辆环境
订单信息结构体 JD_VEHICLE_ORDER_t 中存在字段 iVehicleEnvironment,可通过 get_jd_orderInfo_vehicleEnvironment() 直接读取。该值在 callServer(26)(工厂模式)的 affterHandler 中从 data.vehicleEnvironment 解析填充,代表车辆出厂时的目标环境。
Sources: jidu_orderInfo.cpp, jidu_client.cpp, jidu_macro.h
三、环境切换工单(Environment Change Work Order)
当售后需要将车辆从一个环境切换到另一个环境(如 Staging → Prod),必须先提交工单并经审批流程。本节两个 API 分别负责远程查询工单状态和本地缓存读取。
3.1 远程查询:get_jd_vehicleEnvChangeWorkFlowStatus
| 参数 | 类型 | 说明 |
|---|---|---|
vin | const char* | 车辆 VIN 码 |
carType | int | 车型(MarsOne=1, Venus=2) |
userName | const char* | 操作员用户名 |
env | int | 目标环境 |
action | int | 操作动作 |
调用 callServer(87) → 接口 /uds/vehicle/vehicleEnvChangeWorkFlow/queryStatus(POST),从响应的 data.status 字段解析工单状态:
| 返回值 | 含义 |
|---|---|
1 | 审批中 |
2 | 审批拒绝 |
3 | 审批通过 |
4 | 工单失效 |
5 | 无申请数据 |
-1 | 查询失败 |
请求中携带 deviceSn 用于诊断仪身份识别,carType 和 env 分别标识车型与目标环境。
Sources: jidu_vehicleInfo.cpp
3.2 缓存读取:get_jd_orderInfo_vehicleEnvChangeWorkFlowStatus
从 DataCenter::m_callServerRecord[87].response 缓存中直接解析 data.status 字段,逻辑与远程版本一致。若缓存不存在记录 87,返回 -1。
响应 JSON 结构示例(来自代码注释):
{
"vin": "DAGTEST0000000003",
"status": 5
}Sources: jidu_vehicleInfo.cpp
四、软件版本与升级路径(Software Version Upgrade Path)
这是整个查询体系中最复杂的一部分,涉及6 个请求类型(86/88/89/90/91/92),覆盖从"最后一次 OTA 版本"到"目标版本刷写包匹配"到"升级路径链路"的完整信息链。
4.1 最后一次 OTA 版本:get_jd_lastOtaVersion
调用 callServer(86) → /uds/vsp/vehicleTask/queryByVin(POST),从响应 data[0].targetVersion 提取最近一次 OTA 任务的目标版本号字符串(如 "6100003449 AC")。若 data 是数组则取第一个元素,若为对象则直接解析。
Sources: jidu.cpp
4.2 目标版本刷写包查询:get_jd_vehicleSoftApps
这是升级路径中最关键的步骤——给定目标版本号,查询需要刷写的 ECU 软件包清单。
| 参数 | 说明 |
|---|---|
vin | 车辆 VIN |
carType | 车型 |
targetVersion | 目标软件版本号 |
函数内部构造一个复杂的嵌套 JSON 请求体,遍历 DataCenter::m_vehicleInfo.mapEcuInfo 中所有 ECU(跳过 HWPN 为空的 ECU),为每个 ECU 填入其 name、ecuId(十六进制)、HWPN 和 SWPN。对于 POT ECU 还附加 differentiation 字段(尾翼配置)。
调用 callServer(88) → /uds/vsp/queryVehicleSoftApps(POST),affterHandler 将响应 JSON 中的 data.ecusInfo 数组解析为 JD_ECU_INFO_t 结构体列表,存入 DataCenter::m_VehicleOrderInfo.vecListEcuNew。BECM1/IEM 等 ECU 按 ecuId 做了名称映射(如 0x5051→BECM1_75、0x5071→IEM_IGBT)。
返回值是 vecListEcuNew.size(),即匹配到的 ECU 数量。
Sources: jidu.cpp, jidu_client.cpp
从缓存读取刷写包详情
以下函数从 vecListEcuNew 中按 ECU ID 或名称提取 HWPN/SWPN(均以 \t 分隔多个 SWPN,跳过 SBL 类型):
| 函数 | 匹配方式 | 返回内容 |
|---|---|---|
get_jd_vehicleSoftApps_ecuHwpn_byEcuId(ecuId) | ecuId & 0xFFF0 掩码匹配 | HWPN 字符串 |
get_jd_vehicleSoftApps_ecuSwpn_byEcuId(ecuId) | ecuId & 0xFFF0 掩码匹配 | SWPN 列表(\t 分隔) |
get_jd_vehicleSoftApps_ecuHwpn_byEcuName(ecuName) | 名称精确匹配 | HWPN 字符串 |
get_jd_vehicleSoftApps_ecuSwpn_byEcuName(ecuName) | 名称精确匹配 | SWPN 列表(\t 分隔) |
Sources: jidu.cpp
4.3 按 ECU 获取目标版本:get_jd_vehicleSoftVerByEcu 系列
get_jd_vehicleSoftVerByEcu
从 callServer(89)(/uds/vsp/getVehicleSoftVerByEcu)缓存中提取 data.vehicleSoftNumVer 字段,返回整车软件版本号字符串。
get_jd_vehicleSoftVerByEcu_ecuUpgradePathList
从同一次 callServer(89) 响应中提取 data.ecuUpgradePathList 数组,将其序列化为完整 JSON 字符串返回——这允许 OTX 序列获取每个 ECU 的升级路径明细。
Sources: jidu.cpp
4.4 整车软件升级路径:get_jd_vehicleSoftUpgradePath
调用 callServer(90) → /uds/vsp/getVehicleSoftUpgradePath(POST),从 data.vehicleSoftUpgradePath 数组中提取所有 vehicleSoftNumVer 字段,用分号(;)拼接为一个字符串返回。
响应示例结构(来自代码注释):
{
"vehicleSoftUpgradePath": [
{
"vehicleSoftId": 6232,
"vehicleSoftNumVer": "6200000200 BC",
"hasBridge": false,
"bridgeNumVer": null,
"isBridge": null,
"isOperation": null
}
]
}返回格式:"6200000200 BC;6200000300 BD;..." ——调用方按 ; 分割即可获得有序升级路径。
Sources: jidu.cpp
4.5 基线/目标版本对:get_jd_vehicleVersionInfo
调用 callServer(91) → /uds/vsp/getVehicleVersionInfo(POST),从 data 中同时提取 baselineVersion 和 targetVersion,分别写入两个输出缓冲区。此 API 让诊断仪一次性获取当前基线版本与目标升级版本。
Sources: jidu.cpp
4.6 FOTA 不可行驶状态:get_jd_fotaCanNotDriveByVin 系列
调用 callServer(92) → /uds/afterSale/getFotaCanNotDriveByVin(POST),查询车辆是否存在"因 FOTA 未完成而不可行驶"的状态。提供三个独立提取函数:
| 函数 | 提取字段 | 含义 |
|---|---|---|
get_jd_fotaCanNotDriveByVin_targetVehicleSoftVersion | targetVehicleSoftVersion | 目标升级版本 |
get_jd_fotaCanNotDriveByVin_statusOccurTimestamp | statusOccurTimestamp | 状态发生时间戳 |
get_jd_fotaCanNotDriveByVin_vehicleUpgradeSubStatusMsg | vehicleUpgradeSubStatusMsg | 升级子状态描述 |
三者共享同一个 m_callServerRecord[92] 缓存,分别提取不同字段。
Sources: jidu.cpp
4.7 桥接应用文件 SWPN:get_jd_appBridgeFiles_swpn
调用 callServer(93) → /uds/vsp/app/bridge/getFiles(POST),请求参数为 deviceSn 和 appId。从响应的 data.appFileList 数组中提取每个元素的 softName 字段,用 \t 拼接返回。
该函数是主动调用型(直接调用 callServer 而非仅读缓存),用于查询特定应用的桥接文件 SWPN 列表。
Sources: jidu.cpp
五、请求类型速查表
下表汇总本文档涉及的所有 callServer 请求类型及其对应的 URI 端点:
| iType | 方法 | 主机 | URI 路径 | 用途 |
|---|---|---|---|---|
68 | POST | diag | /uds/vehicle/getCcpInfo | 获取 CCP 任务编号 |
82 | POST | diag | /uds/vehicle/info/queryByVin | 车辆激活状态查询 |
85 | POST | diag | /uds/vehicle/env/getVehicleEnvByVin | 车辆环境状态查询 |
86 | POST | diag | /uds/vsp/vehicleTask/queryByVin | 最近 OTA 任务版本 |
87 | POST | diag | /uds/vehicle/vehicleEnvChangeWorkFlow/queryStatus | 环境切换工单状态 |
88 | POST | diag | /uds/vsp/queryVehicleSoftApps | 目标版本刷写包查询 |
89 | POST | diag | /uds/vsp/getVehicleSoftVerByEcu | 按 ECU 获取目标版本 |
90 | POST | diag | /uds/vsp/getVehicleSoftUpgradePath | 整车软件升级路径 |
91 | POST | diag | /uds/vsp/getVehicleVersionInfo | 基线/目标版本对 |
92 | POST | diag | /uds/afterSale/getFotaCanNotDriveByVin | FOTA 不可行驶查询 |
93 | POST | diag | /uds/vsp/app/bridge/getFiles | 桥接应用 SWPN |
Sources: jidu_uri.h
六、从订单信息中获取车辆环境
除了上述专门的远程查询 API,JD_VEHICLE_ORDER_t 结构体中的 iVehicleEnvironment 字段可通过 get_jd_orderInfo_vehicleEnvironment() 直接读取。该值在工厂模式下由 callServer(26) 的 affterHandler 从 data.vehicleEnvironment 解析填充(同时支持 string 和 number 类型),代表车辆出厂时绑定的目标环境。
Sources: jidu_orderInfo.cpp, jidu_client.cpp
阅读建议
理解本文档后,建议按以下路径继续深入:
- 要理解
callServer的完整路由与签名机制,阅读 callServer 接口设计:请求类型路由、预处理/后处理与脱敏机制 - 要了解
JD_VEHICLE_ORDER_t订单信息的完整获取流程,阅读 DataCenter:车辆订单、安全常量、证书信息的统一缓存中心 - 要理解刷写包如何匹配到具体文件,阅读 CVehicleConfig:整车软件包配置解析与刷写文件匹配策略
- 要了解诊断仪本地环境的切换机制,阅读 EnvConfig:多环境(Dev/Test/Staging/Prod)配置切换机制
- 要理解 FOTA 刷写任务如何编排,阅读 jidu_flasher:刷写任务编排、硬件版本检查与 FOTA 状态跟踪