Skip to content

gRPC, Protobuf & When to Use What

Advanced11 min read
Assumes: 3.3 SOME/IP Deep Dive
TL;DR

gRPC is Google’s RPC framework: HTTP/2 transport, Protocol Buffers (protobuf) serialization, strongly typed service definitions in .proto files. It dominates inter-VM communication (QNX↔AAOS over vsock), cloud backends, and OTA orchestration: anywhere you control both endpoints and want high-throughput, typed APIs. SOME/IP dominates in-vehicle service discovery and ECU-to-ECU communication on Automotive Ethernet. They’re complementary, not competing. Your “lb” OTA tool uses SOME/IP to discover update services on the vehicle bus, then gRPC for the actual data transfer.

If you’ve written a .proto file, run grpcurl, or seen :50051 in a port dump, you’ve touched gRPC. If you’ve used Wireshark on SOME/IP-SD multicast, you’ve touched the other half. Yes, your car runs two different RPC frameworks simultaneously. No, it’s not a design mistake — it’s protocol selection done right. This page explains why both exist in the same vehicle and when to reach for which.

Layer Technology
IDL .proto files: define services, methods, messages
Serialization Protocol Buffers: binary, schema-evolvable, code-generated
Transport HTTP/2: multiplexed streams, header compression, flow control
RPC styles Unary, server streaming, client streaming, bidirectional streaming
Code gen protoc → stubs in C++, Java, Kotlin, Python, Go, etc.
update_service.proto
service UpdateManagement {
rpc StartDownload(StartDownloadRequest) returns (StartDownloadResponse);
rpc StreamProgress(ProgressRequest) returns (stream ProgressUpdate);
rpc GetStatus(StatusRequest) returns (StatusResponse);
}
message StartDownloadRequest {
string package_id = 1;
bytes manifest_hash = 2;
}

One .proto file → client and server stubs in every language. Change the schema, regenerate, compile. Type mismatches fail at build time, not in the field.

Mental Model

If SOME/IP is the vehicle’s internal phone system (departments, extensions, building directory), gRPC is the video conference link between buildings. It doesn’t need to discover who’s in the vehicle — both sides already know the .proto contract and connect directly over a known channel (vsock, TCP, TLS). High bandwidth, typed, streaming-capable. You use it when two systems you control need to talk efficiently, not when a random ECU needs to find a service at runtime.

Mnemonic: gRPC = phone call with a translator (protobuf) built in.

Think About It

SOME/IP and gRPC both provide RPC. Why would you use both in the same vehicle?

Reveal Answer

They solve different boundary problems: SOME/IP-SD dynamically discovers services across Automotive Ethernet ECUs whose IP and port you cannot hardcode at build time, while gRPC connects known endpoints you control — QNX↔AAOS over vsock, OTA bulk transfer, cloud backends — with HTTP/2 streaming, flow control, and protobuf tooling. Your lb OTA tool is the textbook split: SOME/IP finds UpdateManagement and runs small prepare/finalize RPC; gRPC streams the firmware on a separate high-bandwidth channel.

Your cockpit SoC runs QNX and AAOS in separate VMs on the same die. They share no memory. Communication goes through the hypervisor via vsock (virtual socket, like TCP but VM-to-VM without hitting the physical network).

flowchart LR
    subgraph AAOS_VM["AAOS VM"]
        App["Body/HVAC App"]
        HAL["Vehicle HAL<br/>(AIDL)"]
        GRPC_C["gRPC Client"]
        App --> HAL --> GRPC_C
    end

    subgraph Hypervisor["Hypervisor (vsock)"]
        VS["vsock channel<br/>CID:port"]
    end

    subgraph QNX_VM["QNX VM"]
        GRPC_S["gRPC Server"]
        VAL["Vehicle Abstraction<br/>Layer"]
        SOMEIP["SOME/IP Client"]
        GRPC_S --> VAL --> SOMEIP
    end

    GRPC_C <-->|"gRPC / HTTP/2<br/>protobuf"| VS
    VS <-->|"gRPC / HTTP/2<br/>protobuf"| GRPC_S
    SOMEIP -->|"SOME/IP<br/>Automotive Ethernet"| ECU["Zone Controllers / ECUs"]

Why gRPC here, not SOME/IP?

  • Both VMs are controlled by the same team. No runtime discovery needed.
  • High throughput: camera metadata, log streams, bulk config
  • Multi-language: QNX (C++) server, AAOS (Java/Kotlin) client, same .proto
  • Streaming: server-streaming for progress updates during OTA

Telematics, fleet management, and remote diagnostics connect the vehicle to cloud backends:

Use Case Protocol Why
Telemetry upload gRPC streaming Efficient binary, backpressure via HTTP/2
Remote command gRPC unary Typed request/response with auth
Map tile delivery gRPC / HTTP/3 Large payload streaming
OTA manifest fetch gRPC or HTTPS Server-controlled, versioned schema

Cloud endpoints don’t speak SOME/IP. They speak HTTP/gRPC. Your telematics stack on the AP (QNX services) bridges in-vehicle SOME/IP to gRPC/HTTPS toward cloud backends; the modem subsystem (AMSS) is reached separately via QMI, not SOME/IP.

Over-the-air updates involve multiple stages, and different protocols at each:

sequenceDiagram
    participant Cloud as OTA Cloud
    participant Telem as Telematics (QNX/AMSS)
    participant Update as UpdateManagement (SOME/IP)
    participant lb as lb OTA Tool (your laptop)

    Cloud->>Telem: gRPC/HTTPS: push manifest
    Telem->>Update: SOME/IP: notify update available

    lb->>Update: SOME/IP-SD FIND UpdateManagement
    Update->>lb: SOME/IP-SD OFFER (IP:port)
    lb->>Update: SOME/IP method — prepareUpdate()
    lb->>Update: gRPC — stream firmware binary (high bandwidth)
    Update->>lb: gRPC stream — progress callbacks
    lb->>Update: SOME/IP method — finalizeUpdate()
Common Gotcha

Beginner thinks gRPC replaces SOME/IP everywhere once you “modernize” the stack.

Reality: gRPC requires both endpoints to know the .proto and connect directly. ECUs on Automotive Ethernet discover each other dynamically via SOME/IP-SD. gRPC replaces SOME/IP only at boundaries where you control both sides (VM↔VM, tool↔known-service, vehicle↔cloud).

Common Gotcha

If you expose a gRPC service on the vehicle Ethernet without TLS and access control, any node on the VLAN can invoke it.

Unlike SOME/IP-SD (which at least requires knowing service IDs), a gRPC port on a known IP is a direct attack surface. Inter-VM vsock is trusted; vehicle-network gRPC needs authentication — especially for OTA and diagnostic endpoints.

SOME/IP gRPC
Discovery Dynamic (SOME/IP-SD multicast) Static (known host:port or DNS)
Transport UDP + TCP (raw IP) HTTP/2 (TCP or vsock)
Serialization SOME/IP binary (from FIDL) Protocol Buffers (from .proto)
Schema FIDL / ARXML / Franca IDL .proto files
Streaming Events (pub/sub, no backpressure) Native bidirectional streaming with flow control
Ecosystem Automotive-specific (vsomeip, CANoe) Universal (Google, CNCF, every language)
Security SecOC (AUTOSAR), MACsec (Ethernet) TLS/mTLS (standard)
Typical scope In-vehicle ECU ↔ ECU VM ↔ VM, tool ↔ service, vehicle ↔ cloud
Bandwidth Automotive Ethernet (100M–1G) vsock, GigE, cloud (unlimited)
Who defines it AUTOSAR / GENIVI Google / CNCF
Your “lb” tool uses it for Discovering update services on vehicle bus Transferring firmware data and progress

One way to remember: SOME/IP searches on the bus (discovery); gRPC is a guaranteed pipe (direct connection).

Your “lb” OTA tool is a perfect case study in protocol layering:

The tool connects to the vehicle’s Automotive Ethernet (via diagnostic port, test bench, or DoIP gateway). It doesn’t know which IP/port hosts the update service. That depends on the vehicle variant, zone controller assignment, and runtime state.

lb tool → SOME/IP-SD FIND UpdateManagement → OFFER (192.168.1.10:30501)

SOME/IP-SD answers: “The update service is at this address.”

Initial handshake uses SOME/IP RPC, small and automotive-native:

lb tool → SOME/IP REQUEST prepareUpdate(packageId, manifestHash)
← SOME/IP RESPONSE (sessionId, status=READY)

This validates the vehicle is ready, checks version compatibility, and reserves resources, all through the vehicle’s native service layer.

Firmware binaries are hundreds of MB to GB. SOME/IP can handle this (with SOME/IP-TP segmentation), but gRPC is better suited:

  • HTTP/2 flow control: backpressure if the vehicle’s write buffer fills
  • Bidirectional streaming: send chunks while receiving progress
  • Efficient binary serialization: protobuf handles metadata alongside raw bytes
  • Tooling: your laptop runs Python/Go gRPC clients easily; vsomeip setup is heavier
lb tool → gRPC StreamDownload(sessionId) → chunks of firmware
← gRPC stream ProgressUpdate(percent, bytesWritten)

Post-transfer validation returns to SOME/IP. It’s the vehicle’s native service layer:

lb tool → SOME/IP REQUEST finalizeUpdate(sessionId, checksum)
← SOME/IP RESPONSE (status=SUCCESS, rebootRequired=true)
flowchart TB
    subgraph VehicleBus["Vehicle (Automotive Ethernet)"]
        SD["SOME/IP-SD<br/>224.244.224.245:30490"]
        UM["UpdateManagement Service<br/>192.168.1.10:30501"]
        SD --- UM
    end

    subgraph lbTool["lb OTA Tool (your laptop)"]
        LB_SD["SOME/IP Client<br/>(discovery)"]
        LB_GRPC["gRPC Client<br/>(data transfer)"]
        LB_SD --- LB_GRPC
    end

    subgraph Protocols["Protocol Roles"]
        P1["SOME/IP-SD → Find service"]
        P2["SOME/IP RPC → Prepare / Finalize"]
        P3["gRPC → Stream firmware binary"]
    end

    LB_SD -->|"1. FIND/OFFER"| SD
    LB_SD -->|"2. prepareUpdate()"| UM
    LB_GRPC -->|"3. StreamDownload()"| UM
    LB_SD -->|"4. finalizeUpdate()"| UM

    P1 -.-> LB_SD
    P2 -.-> LB_SD
    P3 -.-> LB_GRPC
vsock: Why Not Just Use TCP Between VMs?

vsock (virtual socket) is a socket family where addresses are (CID, port) (Context ID and port) instead of (IP, port). The hypervisor routes vsock packets between VMs without touching the physical NIC. Benefits: no IP configuration, no port conflicts with vehicle Ethernet, lower latency (no network stack traversal), and security isolation (VMs can’t sniff each other’s vsock unless explicitly bridged). gRPC over vsock is the standard pattern for QNX↔AAOS on Qualcomm platforms. You’ll see CID 2 for AAOS and CID 3 for QNX (exact values vary by platform config).

flowchart TD
    Start["Need to communicate?"]
    Start --> Q1{"Both endpoints<br/>you control?"}
    Q1 -->|"No — vehicle ECUs<br/>discover dynamically"| SOMEIP["Use SOME/IP<br/>+ SOME/IP-SD"]
    Q1 -->|"Yes"| Q2{"On vehicle Ethernet<br/>with other ECUs?"}
    Q2 -->|"Yes — but you control<br/>both sides (VM, tool)"| Q3{"High bandwidth<br/>or streaming?"}
    Q2 -->|"No — VM, cloud,<br/>or dev tool"| GRPC["Use gRPC<br/>+ protobuf"]
    Q3 -->|"Yes — firmware,<br/>logs, camera meta"| GRPC
    Q3 -->|"No — small RPC,<br/>discovery needed"| SOMEIP
Scenario Protocol Reason
Zone controller ↔ QNX gateway SOME/IP Dynamic discovery, automotive-native
QNX ↔ AAOS (same SoC) gRPC over vsock Controlled endpoints, high throughput
OTA tool ↔ vehicle (discovery) SOME/IP-SD Don’t know service address at build time
OTA tool ↔ vehicle (data transfer) gRPC Streaming, flow control, large payloads
Vehicle ↔ cloud backend gRPC / HTTPS Standard internet protocols
ADAS sensor fusion DDS Rich QoS, topic-based pub/sub
Legacy body ECU ↔ zone controller CAN signals MCU can’t run SOME/IP or gRPC
Where You'll See This

You’ll interact with both protocols regularly:

  • .proto files in the repo: search for UpdateManagement, VehicleProperty, TelemetryService. These define the gRPC contract between QNX and AAOS (or tool and vehicle).
  • protoc / Gradle codegen: AAOS builds generate Java/Kotlin stubs; QNX builds generate C++ stubs. IDL mismatch between VMs = runtime deserialize errors.
  • grpcurl / lb tool: when testing OTA or vehicle services from your laptop, you’ll use gRPC for data and SOME/IP for discovery. Know which flag controls each.
  • vsock port maps: platform docs list which gRPC services listen on which (CID, port). “Connection refused on vsock:50051” = QNX gRPC server not running or wrong CID.
  • Wireshark: filter someip for vehicle bus traffic, filter grpc || http2 for vsock/cloud traffic. Different filters, different debug skills.
  • Logs: QNX gRPC server logs show StreamDownload started; vsomeip logs show OFFER/Find. Combined OTA failure? Check BOTH log streams.

Debugging checklist for “lb OTA failed”:

  1. SOME/IP-SD: Did Find get an Offer? (If no → network/VLAN issue)
  2. SOME/IP RPC: Did prepareUpdate succeed? (If no → version/state issue)
  3. gRPC: Did StreamDownload connect and send chunks? (If no → vsock/port/firewall)
  4. SOME/IP RPC: Did finalizeUpdate succeed? (If no → checksum/validation issue)

Each phase uses a different protocol. Debug them independently.

Connect the Dots

Module 3.1 (Signals) is the legacy layer still running on MCUs. Module 3.2 (SOA) explains the service paradigm. Module 3.3 (SOME/IP) is the in-vehicle wire protocol. This page completes the picture with gRPC for controlled-endpoint communication. Module 5 (Qualcomm Cockpit) shows vsock CID assignments. Module 8 (Flashing & OTA) walks through the full update flow your “lb” tool implements.

  1. gRPC = HTTP/2 + protobuf + strongly typed .proto, for when you control both endpoints.
  2. SOME/IP = dynamic discovery + automotive-native RPC, for in-vehicle ECU communication.
  3. They’re complementary: SOME/IP finds services, gRPC moves bulk data.
  4. Your “lb” OTA tool uses SOME/IP for discovery/prepare/finalize and gRPC for firmware streaming.
  5. QNX↔AAOS uses gRPC over vsock, not SOME/IP, not TCP to an IP address.

Check Your Understanding

1. What serialization format does gRPC use for on-the-wire message encoding?

Recall

2. Why does the lb OTA tool use SOME/IP for discovery but gRPC for firmware transfer?

Applied

3. QNX and AAOS on the same SoC communicate via gRPC over vsock instead of SOME/IP. Why?

Applied

4. A zone controller offers DoorService via SOME/IP. An AAOS app wants to lock a door. What's the typical communication chain?

Applied

5. Your lb OTA tool's prepareUpdate SOME/IP call succeeds, but gRPC StreamDownload fails with connection refused. SD shows UpdateManagement is Offered. Most likely explanation?

Synthesis

Connects to: Module 8 — OTA In Practice

6. A telematics service must upload vehicle telemetry to a cloud backend over LTE. Which protocol boundary is correct?

Synthesis

Connects to: Module 7 — AMSS & Telematics

Module Review: Signals to Services

Question 1 of 10

Legacy signal: BCM sends TurnSignalLeft ON via CAN ID 0x2A0 byte 3 bit 1. SOA equivalent: BodyService.TurnSignal field. A test bench simulates the CAN signal but the cluster doesn't show the indicator. The cluster consumes SOME/IP, not CAN. What's missing?

🔗 Connects to: Module 4 — Signal-to-Service Transformers

Further Reading