Skip to content

OTA In Practice: gRPC + SOME/IP

TL;DR

Production automotive OTA isn’t just Android UpdateEngine. It’s a distributed update architecture spanning cockpit SoC, zone controllers, modem, and ADAS ECUs. SOME/IP handles service discovery and control-plane RPC: finding which ECU offers UpdateManagement, subscribing to progress events, coordinating preconditions (speed, power). gRPC handles data-plane transfer: streaming signed payloads, manifest delivery, status callbacks with protobuf contracts. Your daily lb tool sits in the campaign orchestration layer. It drives gRPC sessions to update agents, uses SOME/IP to discover targets on the vehicle network, and manages fleet campaigns while UpdateEngine (or capsule/TelAF equivalents) does the actual slot writing on each compute unit.

You run lb campaigns every week. This page connects the tool you touch to the protocols underneath, and where Android UpdateEngine ends and vendor OTA begins.

A modern SDV OTA stack has layers, not one daemon:

flowchart TB
subgraph Cloud["Backend / Campaign Server"]
CMS["Campaign Management<br/>build matrix, targeting"]
PKG["Package Repository<br/>signed payloads"]
end
subgraph Bench["Your Workstation"]
LB["lb tool<br/>campaign CLI"]
end
subgraph Vehicle["In-Vehicle Network"]
subgraph Cockpit["Cockpit SoC (SA8155P)"]
GW["OTA Gateway / Update Agent"]
UE["UpdateEngine (AAOS)"]
GW --> UE
end
subgraph Zone["Zone Controller"]
CAP["Capsule Update Agent"]
end
subgraph Modem["Modem / TelAF"]
TAF["TelAF OTA Client"]
end
end
CMS --> LB
PKG --> LB
LB -->|"gRPC: stream payload, control"| GW
LB -->|"SOME/IP: discover + method calls"| GW
LB -->|"SOME/IP + gRPC"| CAP
LB -->|"SOME/IP + gRPC"| TAF
GW -->|"internal API"| UE
Layer Responsibility Example Component
Campaign orchestration Target selection, scheduling, retry, reporting lb, fleet backend
Transport Discovery, session setup, streaming SOME/IP + gRPC
Update agent Preconditions, local apply, reboot coordination Gateway service on each ECU
Platform engine Partition/slot manipulation UpdateEngine, capsule, TelAF
Boot firmware Slot selection, AVB ABL, bootctrl

lb orchestrates, SOME/IP finds agents, gRPC feeds payloads, and UpdateEngine writes slots.

Mental Model

Think of a fleet OTA as airport catering. SOME/IP is the intercom — “Which gate has the catering port open?” gRPC is the conveyor belt — meals (payload bytes) streamed to the right gate. lb is the ** catering manager’s tablet** — selects flights (VINs), starts deliveries, reads status. UpdateEngine is the flight crew — actually loads trays into the galley (inactive slot) once delivery arrives.

SOME/IP: Service Discovery for Update Targets

Section titled “SOME/IP: Service Discovery for Update Targets”

SOME/IP (Scalable service-Oriented MiddlewarE over IP) runs on Automotive Ethernet, the same SOA fabric from Module 3.

SOME/IP Feature OTA Use
Service Discovery (SD) Find UpdateManagement instances on unknown ECUs
Methods (RPC) StartDownload(), GetStatus(), CancelUpdate()
Events ProgressChanged(42%), PreconditionFailed(SPEED)
Fields CurrentVersion, UpdateState
Multicast/UDP SD ECUs announce services without static IP tables

Typical discovery flow:

  1. lb (or in-vehicle gateway) sends FindService for UpdateManagement (service ID program-specific)
  2. Zone controller responds OfferService with IP, port, instance ID
  3. lb invokes StartDownload(campaignId, manifestUrl) via SOME/IP method
  4. Agent publishes ProgressChanged events during apply
Common Gotcha

SOME/IP service IDs and method signatures are OEM-defined, not standardized like Android APIs. Your lb config maps logical names to ARXML/VSOMEIP configs. Copying SOME/IP IDs from another program will silently find no services or call wrong methods.

While SOME/IP handles in-vehicle service semantics, gRPC (HTTP/2 + protobuf) typically handles:

gRPC Role Details
Payload streaming Client/server streaming of multi-GB OTA packages
Manifest delivery Protobuf-defined package metadata, hash, rollback index
Status callbacks Structured error codes back to campaign tool
Authentication mTLS, token-based fleet auth
Cross-network Bench PC → vehicle gateway over Ethernet/Wi-Fi

Example logical service (conceptual; actual .proto is vendor-specific):

service UpdateDelivery {
rpc StreamPackage(PackageRequest) returns (stream PackageChunk);
rpc ReportStatus(StatusReport) returns (Ack);
rpc QueryCapabilities(Empty) returns (CapabilityList);
}
Transport Best For
SOME/IP In-vehicle ECU-to-ECU, SD, real-time preconditions
gRPC High-throughput blob transfer, cloud-to-vehicle, tool-to-gateway
HTTPS Classic UpdateEngine server check (AAOS A/B)

Many architectures use both: SOME/IP discovers the agent and gates preconditions; gRPC streams the blob to the agent’s local cache; agent hands off file path to UpdateEngine.

Your lb tool (vendor OTA CLI; exact expansion varies by OEM/Tier-1) typically implements:

lb Capability What You Do Daily
Campaign create Target build ID, VIN list, rollout percentage
Precondition check Speed, voltage, storage space, current build match
Trigger download Initiate gRPC stream or point agent to CDN URL
Monitor progress Parse SOME/IP events or gRPC status stream
Retry / abort Cancel stuck campaigns, restart failed ECUs
Multi-ECU orchestration Sequence: modem → zone → cockpit (dependency order)
Report export Pass/fail per ECU for test sign-off

Typical daily workflow:

Terminal window
# Conceptual; exact syntax is vendor-specific
lb campaign create --build 2024.09.12.001 --targets bench-vin-list.txt
lb campaign preflight --campaign-id 8842
lb campaign start --campaign-id 8842
lb campaign status --campaign-id 8842 --watch
lb campaign logs --ecu cockpit --since 1h
lb campaign debugging checklist

When a campaign stalls at 0%:

  1. SOME/IP SD: Is the update service offered? (vsomeip log, Wireshark SD packets)
  2. Preconditions: Speed, gear, battery logs in agent events
  3. gRPC connectivity: mTLS cert expiry, firewall on bench VLAN
  4. Build fingerprint match: delta payload against wrong source version
  5. Storage: /data/ota_package or cache partition full
  6. Concurrent merge: Virtual A/B merge blocking apply (Page 8.5)

When cockpit succeeds but zone fails, you’re in multi-ECU orchestration territory. Check lb dependency graph: some programs require modem before AAOS, or zone before cockpit display sync.

Separate transport failures from apply failures: gRPC 200 + UpdateEngine kPayloadHashMismatchError = bad payload, not bad network.

Platform Engines: Who Actually Writes the Slot

Section titled “Platform Engines: Who Actually Writes the Slot”
Engine Platform Mechanism
Android UpdateEngine AAOS on cockpit SoC A/B or Virtual A/B payload apply to UFS partitions
Capsule update AUTOSAR Adaptive / zone controllers Software Cluster packaging, UCM (Update Configuration Management)
TelAF (Telematics AF) Qualcomm modem / telematics Firmware OTA for AMSS, managed service lifecycle
QNX SLM / custom QNX host OS Vendor-specific image swap, may parallel AAOS OTA
Aspect UpdateEngine (Android) Capsule (Adaptive) TelAF (Modem)
Partition model GPT A/B slots, super UCM software clusters Modem firmware store
Payload format .bin OTA payload (Google) AUTOSAR package / manifest QTI modem OTA format
Discovery Often localhost from gateway SOME/IP to UCM service Service-based on internal bus
Rollback bootctrl + AVB UCM rollback API Modem anti-rollback fuses
Typical agent AAOS system service Adaptive application TelAF daemon
Your tool visibility adb logcat update_engine SOME/IP trace + UCM logs lb modem status + QXDM
sequenceDiagram
participant LB as lb tool
participant SD as SOME/IP SD
participant GW as Cockpit Update Agent
participant GRPC as gRPC stream
participant UE as UpdateEngine
LB->>SD: FindService(UpdateManagement)
SD-->>LB: OfferService (192.168.x.x)
LB->>GW: StartDownload (SOME/IP method)
GW->>GW: Check preconditions (speed=0, power OK)
LB->>GRPC: StreamPackage(manifest)
GRPC->>GW: Payload chunks
GW->>UE: ApplyPayload(path)
UE->>UE: Write inactive slot
UE-->>GW: UPDATED_NEED_REBOOT
GW-->>LB: ProgressEvent(100%)
LB->>GW: ConfirmReboot (policy-gated)
GW->>UE: Reboot
When UpdateEngine Runs vs Gateway Proxy

Some programs embed UpdateEngine directly in the AAOS update app: lb talks gRPC to a cloud backend, Android downloads via HTTPS. Others place an OTA gateway on QNX or a privileged Android service that proxies to UpdateEngine via binder IPC, so lb never touches UpdateEngine directly. Check your program’s sequence diagram in the integration spec to know where your logs live.

Every engine hits the same gates:

Gate Where Enforced
Payload signature UpdateEngine / UCM before apply
Rollback index ABL + modem fuses
AVB match First boot after apply
Campaign signing Backend + lb mTLS / package signature

A perfectly delivered gRPC stream still fails if the payload wasn’t signed with the production OTA key matching fused trust anchors.

Connect the Dots

Module 3 (SOA) introduced SOME/IP primitives: methods, events, fields. Page 8.5 covered A/B slot mechanics UpdateEngine implements. Page 8.3 gives ADB commands for UpdateEngine log grep. Page 8.2 (QFIL) remains the recovery path when OTA bricks both slots.

  1. lb orchestrates campaigns. It doesn’t write partitions directly.
  2. SOME/IP = in-vehicle discovery + control plane. gRPC = payload streaming + structured status.
  3. UpdateEngine, capsule, and TelAF are platform-specific apply engines under the agent.
  4. Debug by layer: SD connectivity → gRPC transfer → precondition → apply engine → AVB boot.

Check Your Understanding

1. In a typical automotive OTA stack, what is SOME/IP primarily responsible for?

2. Where does the lb tool sit in the OTA architecture?

3. Cockpit AAOS OTA succeeds via UpdateEngine, but a zone controller fails. Most likely architectural explanation?