How to Design a Simple SOME/IP Service Discovery Demo

Gengini Engineering Team
Gengini Engineering Team
  • Jul 07 2026
  • 10 min to read
How to Design a Simple SOME/IP Service Discovery Demo

If you're evaluating SOME/IP for a new project, the fastest way to build intuition is to run a minimal service discovery demo before touching AUTOSAR tooling. This guide walks through building a two-node SOME/IP setup — one offering a service, one finding and calling it — using the open-source vsomeip stack on Linux, with an optional QEMU step to simulate two separate ECUs.

Why Build This First

Service discovery (SOME/IP-SD) is the part of the stack most engineers get wrong first: multicast configuration, offer/find timers, and TTL handling behave differently than a REST API or a simple UDP broadcast. Building a minimal demo surfaces these issues in an environment you control, before you're debugging them on real vehicle network hardware.

Prerequisites

  • Linux host (Ubuntu 22.04 or later recommended)
  • vsomeip and its dependency boost installed
  • Basic familiarity with C++ and JSON configuration files
  • Optional: QEMU with two Linux VMs bridged on a virtual network, to simulate two ECUs

Install vsomeip from source:

git clone https://github.com/COVESA/vsomeip.git
cd vsomeip
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig

Step 1: Define the Service Interface

SOME/IP identifies services by a service ID, instance ID, and method/event IDs — there's no interface description language required for a minimal demo, just consistent IDs on both sides.

// service_ids.hpp
#define SAMPLE_SERVICE_ID   0x1234
#define SAMPLE_INSTANCE_ID  0x5678
#define SAMPLE_METHOD_ID    0x0421

Step 2: Configure the Service (Offering Node)

vsomeip is configured via JSON. This defines a service that offers itself on the network and responds to a method call:

{
    "unicast": "10.0.3.1",
    "logging": { "level": "info", "console": "true" },
    "applications": [
        { "name": "service-sample", "id": "0x1111" }
    ],
    "services": [
        {
            "service": "0x1234",
            "instance": "0x5678",
            "unreliable": "30509"
        }
    ],
    "service-discovery": {
        "enable": "true",
        "multicast": "224.244.224.245",
        "port": "30490",
        "protocol": "udp"
    }
}

The service application code registers a message handler and calls offer_service():

app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
app_->register_message_handler(
    SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID,
    [this](const std::shared_ptr<vsomeip::message> &request) {
        auto response = vsomeip::runtime::get()->create_response(request);
        app_->send(response);
    });

Step 3: Configure the Client (Finding Node)

The client's configuration mirrors the service side but with its own unicast address and no services block — it relies on discovery to find the offering node:

{
    "unicast": "10.0.3.2",
    "applications": [
        { "name": "client-sample", "id": "0x2222" }
    ],
    "service-discovery": {
        "enable": "true",
        "multicast": "224.244.224.245",
        "port": "30490",
        "protocol": "udp"
    }
}

The client requests the service and registers an availability handler:

app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
app_->register_availability_handler(
    SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
    [this](vsomeip::service_t, vsomeip::instance_t, bool is_available) {
        if (is_available) {
            auto request = vsomeip::runtime::get()->create_request();
            request->set_service(SAMPLE_SERVICE_ID);
            request->set_instance(SAMPLE_INSTANCE_ID);
            request->set_method(SAMPLE_METHOD_ID);
            app_->send(request);
        }
    });

Step 4: Run It

Set the VSOMEIP_CONFIGURATION environment variable per process and start the service before the client:

VSOMEIP_CONFIGURATION=service.json ./service_sample &
sleep 1
VSOMEIP_CONFIGURATION=client.json ./client_sample

You should see the client log a discovery event followed by a successful method response. If nothing happens within a few seconds, jump to the troubleshooting checklist below.

Step 5 (Optional): Split Across Two QEMU VMs

To simulate two separate ECUs instead of two processes on one host:

  1. Create a bridged network (br0) on the host connecting two QEMU guest NICs.
  2. Assign 10.0.3.1 to VM A (service) and 10.0.3.2 to VM B (client).
  3. Confirm multicast forwarding is enabled on the bridge — this is the step people skip, and it's the one that breaks discovery.
sudo brctl addbr br0
sudo brctl stp br0 off
sudo ip link set br0 up

Troubleshooting Checklist

  • Can both hosts ping each other on the configured unicast addresses?
  • Is multicast traffic actually reaching both hosts? Verify with tcpdump -i <iface> udp port 30490.
  • Do both configs use the exact same multicast address and SD port?
  • Are the service ID, instance ID, and method ID identical (including base) on both sides?
  • Is a firewall (ufw, iptables) blocking UDP 30490 or the ephemeral port range?
  • If running in Docker, is the container network mode host or does it have multicast routing configured? (Bridge networking drops multicast by default.)

What to Build Next

Once this baseline works, extend it incrementally:

  • Add an event/notification (pub/sub) alongside the request/response method
  • Add a second instance of the same service ID to test instance-level discovery filtering
  • Introduce artificial network partition (drop the multicast interface briefly) to observe SD's re-offer/re-find behavior and TTL expiry

This minimal setup is the fastest path to real intuition about SOME/IP's discovery mechanics — far faster than starting with a full AUTOSAR ARXML-driven toolchain.

Categories: Automotive Middleware, Embedded Systems

Tags: SOME/IP, Service Discovery, Linux, QEMU

Share on:
Gengini Engineering Team
Gengini Engineering Team

The Gengini Engineering Team writes practical guides on AI automation, automotive middleware, embedded firmware, cloud software, and industrial IoT systems.

DDS vs MQTT vs SOME/IP: Choosing the Right Communication Middleware

A decision framework for choosing between DDS, MQTT, and SOME/IP based on topology, QoS needs, and deployment constraints.

Read More
SOME/IP vs DDS: Practical Comparison for Automotive Middleware

A practical engineering comparison of SOME/IP and DDS for automotive middleware, SDV platforms, and service-oriented architectures.

Read More
Troubleshooting SOME/IP Service Discovery in Linux and Docker

A diagnostic playbook for fixing SOME/IP service discovery failures caused by multicast routing, Docker networking, and firewall misconfiguration.

Read More